Reputation: 111
i'm trying to learn some clojure, and now i'm stuck whith sequence. I whant to create a new sequence from existing, but newone must contain only top level elements or sum of all nested. For example, from '(1 2 (3 4)) there must be '(1 2 7). I think i'm on the right way to nailed it, but i've got an error:
user=> (make-new '(1 2 (3 4)))
IllegalArgumentException Don't know how to create ISeq from: java.lang.Long
clojure.lang.RT.seqFrom (RT.java:505)
Here's my code:
(defn sum
[list]
(reduce + (into-array (flatten list))))
(defn make-head
[item]
(if (seq? (first item))
(sum (first item))
item
))
(defn make-new
[list]
(cons(make-head (first list)) (seq (make-new (rest list)))))
Hope someone can help me. Thanks.
Upvotes: 1
Views: 156
Reputation: 33637
You could also try for
:
(for [i '(1 2 (3 4))]
(if (seq? i)
(reduce + i)
i))
Upvotes: 0
Reputation:
Remove first
from make-head
, as you're already calling first
from make-new
:
(defn make-head [item]
(if (seq? item)
(sum item)
item))
Also, just use (map make-head list)
in make-new
. There's no need to implement map
yourself:
(defn make-new [list]
(map make-head list))
Finally, +
already reduces (it's variadic), so you can just implement sum
like this:
(defn sum [list]
(apply + (flatten list))
A more concise approach, exploiting the fact that (flatten [42])
results in (42)
:
(defn make-new [xs]
(map #(apply + (flatten [%])) xs))
Upvotes: 3