# More Working With Data Structures

``````(def a [1 2 3])
(map some-fn a)

(map + [1 2 3] [4 5 6])  # => @[5 7 9]

(map tuple
[1 2] ["a" "b"] [:x :y])  # => @[(1 "a" :x) (2 "b" :y)]
# This works too (but you have to put as many args as arrays).
(map |[\$0 \$1 \$2]
[1 2] ["a" "b"] [:x :y])  # => @[(1 "a" :x) (2 "b" :y)]

(zipcoll [:a :b :c] [1 2 3])   # => @{:c 3 :a 1 :b 2}

# Use `;` ("splice") to unpack values:
(def a [1 2 3]) # a tuple
(array ;a)      # => @[1 2 3]

(filter even? (range 10))                      # => @[0 2 4 6 8]
(interleave [:a :b :c] [1 2 3] ["x" "y" "z"])  # => @[:a 1 x :b 2 y :c 3 z]
(interpose 100 (range 5))                      # => @[0 100 1 100 2 100 3 100 4]

(frequencies [:w :w :x :w :y :y])              # => @{:w 3 :x 1 :y 2}

(map |(\$ :type)
[{:type "cat" :name "Fluffy"}
{:type "dog" :name "Spot"}])
# => @["cat" "dog"]

(map string/from-bytes "hello")
# => @["h" "e" "l" "l" "o"]

(def t {:a 1 :b 2 :c 3})
(kvs t)    # => @[:c 3 :a 1 :b 2]
(pairs t)  # => @[(:c 3) (:a 1) (:b 2)]

# Make a table from pairs.
(from-pairs [[:a 1] [:b 2] [:c 3]])  # => @{:a 1 :b 2 :c 3}

# Make a table from an array.
(partition 2 [:a 1 :b 2 :c 3])  # => @[(:a 1) (:b 2) (:c 3)]
(from-pairs
(partition 2 [:a 1 :b 2 :c 3]))  # => @{:a 1 :b 2 :c 3}
# or
(table ;[:a 1 :b 2 :c 3])          # => @{:a 1 :b 2 :c 3}

# Make a new table from a struct:
(table ;(kvs my-struct)) # or
(merge my-struct)

# My own `cycle`.
(def a [44 55 66])

(defn cycle
[a n]
(let [ln (length a)]
(seq [i :range [0 n]]
(a (% i ln)))))

(pp (cycle a 8)) # => @[44 55 66 44 55 66 44 55]

# Note, although Janet doesn't support lazy evaluation per se, you could
# return a "thunk" --- function you will possibly call later on for its return
# value. If you never call/realize the thunk, then no work is done.
(def data [3 2 1])
(def sorted-data-thunk |(sorted data))
# Later...
(def sdata (sorted-data-thunk))``````

# Lazy Seqs

You can do these manually. See https://github.com/janet-lang/janet/blob/master/examples/lazyseqs.janet.

# Sorting

Note that `sort` and `sort-by` sort in-place, whereas `sorted` and `sorted-by` return a new sorted array. Also note:

• The function you pass as the 2nd arg to `sort` must be able to take two args and compare them returning a boolean (like `>`, `<`, etc.).
• The function you pass to `sort-by` just takes one arg: the object you look at to figure out the value you want to sort on, which is what it then returns. Then `<` is used by default to sort by that.

For example:

``````(def a @[22 11 55 44])
(sort a)
(sort a >)   # instead of `<`

(defn f [x] (get-some-value-from x))
(sort-by f a)``````

# `any?`, `every?`, `some`

`any?` is an optimist. It goes through the array looking for and returning the first truthy value it finds (otherwise returns `nil`).

`every?` is a pessimist. It goes through and only returns `true` if every value is truthy (otherwise returns the first falsey value it finds).

`some` needs you to first pass it a predicate function, and goes through the array calling that pred on each item; if that pred call returns truthy, then that truthy return value is returned.

If you want a function that takes a pred and a list, and returns the first item for which `(pred item)` returns truthy, then you’ll have to write that one yourself as shown below. You could also use `find`.

``````(any? [nil false "hey" 5 nil])  # => "hey"

(every? [0 1 "hey"])            # => true
(every? [0 1 "hey" false 7])    # => false
(every? [0 1 "hey" nil   7])    # => nil

(some even? [43 45 46 49])      # => true
(some even? [43 45 47 49])      # => nil

(some (fn [n]
(if (even? n) n))
[43 45 46 49])            # => 46

(find even? [43 45 46 49])      # => 46
(find even? [43 45 47 49])      # => nil

(find-index even?
[43 45 46 49])      # => 2``````