irisk
irisk

Reputation: 111

Create new sequence from existing

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

Answers (2)

Ankur
Ankur

Reputation: 33637

You could also try for:

(for [i '(1 2 (3 4))]
  (if (seq? i)
    (reduce + i)
    i))

Upvotes: 0

user1804599
user1804599

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

Related Questions