If I have a function that takes 3 arguments, and returns a list:
(some-function 1 2 3) --> '(3 2 1)
and I have a list of lists like this:
( (1 2 3) (2 1 3) (3 2 1) )
How can I map "some-function" to use all the lists as elements?
Thank you.
If the lists are only nested once then it is possible to turn them into a single list using fold and append and call some-function on the result with apply i.e
(fold append '() '((1 2 3) (2 1 3) (3 2 1))) => (2 3 1 3 2 1 1 2 3)
(apply some-function (2 3 1 3 2 1 1 2 3))
Otherwise you can just wrap apply and the some-function in a lambda you pass to map
(map (lambda (x) (apply some-function x)) '((1 2 3) (2 1 3) (3 2 1)))
I am not sure what result you mean.
(define (rev-list a b c)
(list c b a))
(rev-list 1 2 3)
⇒ (3 2 1)
(apply rev-list '((1 2 3) (2 1 3) (3 2 1)))
⇒ ((3 2 1) (2 1 3) (1 2 3))
(map (lambda (l) (apply rev-list l)) '((1 2 3) (2 1 3) (3 2 1)))
⇒ ((3 2 1) (3 1 2) (1 2 3))
Related
I want to take a sequence of sequences and sum up each inner sequence.
Data ((1 2 3) (2 3 4) (3 4 5) (4 5 6))
Desired output ((6) (9) (12) (15)) or (6 9 12 15)
I've tried apply map + which doesn't give the desired output. I've also experimented with reduce.
(map #(apply + %) '((1 2 3) (2 3 4) (3 4 5) (4 5 6)))
;; => (6 9 12 15)
(map #(list (apply + %)) '((1 2 3) (2 3 4) (3 4 5) (4 5 6)))
;; => ((6) (9) (12) (15))
For example the list '((1 2 3) (2 3 4) (4 5 6))
result (1 2 3 2 3 4 4 5 6)
(
define (concatenate list1 list2)
(if (null? list1)
list2
(
(concatenate (cdr list1) (append (car list1) '()) )
)
)
)
My idea is list1 = '((1 2 3) (2 3 4) (4 5 6)) and the result is list2 = (1 2 3 2 3 4 4 5 6)
We only need one list parameter, given that it's already a list of lists, and there's no use for a second parameter to be used as an accumulator. Try this:
(define (concatenate lsts)
(apply append lsts))
(concatenate '((1 2 3) (2 3 4) (4 5 6)))
=> '(1 2 3 2 3 4 4 5 6)
Is there a core function or some idiomatic way to do a "reverse flattening" of a collection?
E.g. I would like the following:
(by-two '(1 2 3 4 5 6)) ; evals to '( (1 2) (3 4) (5 6) )
Of course the form in the above case would need an even number of elements or the function should do something sensible if presented with an odd-numbered collection. A generalized by-n function would be better of course. It's not clear to me whether there's any merit in trying to generalize the concept in depth as well or what's the best form to do so:
(by [2 2] '(1 2 3 4 5 6 7 8)) ; evals to '( ( (1 2) (3 4) ) ( (5 6) (7 8) ) )
(by [3 2 1 1 1] '(1 2 3 4 5 6)) ; evals to '(((((1 2 3) (4 5 6)))))
You can use reduce and partition :
(reduce #(partition %2 %1) '(1 2 3 4 5 6 7 8) [2 2])
There's partition:
(partition 2 [1 2 3 4 5])
> ((1 2) (3 4))
If you want to include the small tail, there's partition-all:
(partition-all 2 [1 2 3 4 5])
> ((1 2) (3 4) (5))
There is no such standard function I aware of. But partition is helpful:
(defn by [sizes coll]
(if sizes
(by (next sizes) (partition (first sizes) coll))
coll))
For demonstration purpose,
I have list with has a list:
> (setf x (list '(1 2 1) '(4 5 4)))
((1 2 1) (4 5 4))
> (length x)
2
I want to add a new list '(2 3 2) to it. The append function:
> (append '(2 3 2) x)
(2 3 2 (1 2 1) (4 5 4))
> (length (append '(2 3 2) x))
5
isn't really doing what I want.
What I want is to add '(2 3 2) like this:
((8 7 8) (1 2 1) (4 5 4))
so that the length is 3.
So far, I haven't seen any example or ways to do what I want. Is there a built-in function or effective way of doing this ?
APPEND is not a destructive function, which is what you are asking for. What APPEND does is allocate a new list, which it then returns.
What you can do to achieve your goals is:
(setf x (append '((...)) x)) ;;appends the quoted list to x
There is also the function NCONC, which adjusts pointers destructively.
For your meditations, I present example work:
CL-USER> (defparameter *x* nil)
*X*
CL-USER> (setf *x* '((1 2 3) (4 5 6)))
((1 2 3) (4 5 6))
CL-USER> (append *x* '(10 11 12))
((1 2 3) (4 5 6) 10 11 12)
CL-USER> (append *x* '((10 11 12)))
((1 2 3) (4 5 6) (10 11 12))
CL-USER> (setf *x* (append *x* '((10 11 12))))
((1 2 3) (4 5 6) (10 11 12))
CL-USER> *x*
((1 2 3) (4 5 6) (10 11 12))
CL-USER>
APPEND appends lists. If you have a list of two sublists ((1 2 1) (4 5 4)) and you want to append another list of one sublist ((2 3 2)) in front of it.
CL-USER 99 > (append '((2 3 2)) '((1 2 1) (4 5 4)))
((2 3 2) (1 2 1) (4 5 4))
or use this, if you want to add one item in front of the list:
CL-USER 98 > (cons '(2 3 2) '((1 2 1) (4 5 4)))
((2 3 2) (1 2 1) (4 5 4))
I completed exercise 43 on 4clojure the other day and checked some of the other solutions. One in particular has confused me.
The challenge asks you to write a function which satisfies all of these:
(= (__ [1 2 3 4 5 6] 2) '((1 3 5) (2 4 6)))
(= (__ (range 9) 3) '((0 3 6) (1 4 7) (2 5 8)))
(= (__ (range 10) 5) '((0 5) (1 6) (2 7) (3 8) (4 9)))
My solution was this:
(fn [l n]
(map #(map second %) (vals (group-by #(mod (first %) n)
(map vector (iterate inc 0) l)))))
User himself had this solution:
#(apply map list (partition %2 %1))
and I couldn't work out how it worked.
Let's work through the first problem:
(= (__ [1 2 3 4 5 6] 2) '((1 3 5) (2 4 6)))
well the (#(partition %2 %1) [1 2 3 4 5 6] 2) would give us ((1 2) (3 4) (5 6)) now how does apply map list on that produce (1 3 5) (2 4 6)
apply is using the ((1 2) (3 4) (5 6)) as a variable length list of additional arguments. Then iteration of the map is applying the list function to all three of these additional lists.
As a result it expands as follows:
(apply map list '((1 2) (3 4) (5 6)))
=> (map list '(1 2) '(3 4) '(5 6))
=> (list 1 3 5) and (list 2 4 6)