Reputation: 5438
I started with a csv-file. I have slurped it and added some structure with partition-by
and sorted with sort-by
. But now I'd like to add values to keep track of processing. But get-in
and assoc-in
don't like lists. And although I haven't added lists the partition-by
seems to like them.
So, how to get out of this situation? Is there a way to transform all lists inside a structure to vectors or an alternative version of partition-by
that isn't such a crybaby about lists or do I need to rethink my solution somehow? :-)
A simple example of a structure
(sort '(1 2 3 4 5))
Upvotes: 1
Views: 156
Reputation: 6509
If your structure is a list of lists called xs
, then you can:
(mapv vec xs)
That will give you a vector of vectors. A vector is an associative data structure (unlike a list), so get-in
and assoc-in
will work. However if there are more meaningful keys than the position of an element in a vector, then you might prefer to work with maps, in which case you would have a collection (vector or list) of homogeneous maps, which is a common way of working with data.
And just for verification:
(mapv vec '((1 2 3) (4 5 6)))
;;=> [[1 2 3] [4 5 6]]
Upvotes: 0
Reputation: 3014
If you want to transform the lists and then use the associative interface, clojure.walk
has utilities that allow you to do that transformation on arbitrarily nested structures.
(let[my-nested-structure {:foo '(1 2 4) '(0) :bar :baz {42 '()}}]
(clojure.walk/postwalk #(if (list? %) (vec %) %) my-nested-structure))
;; => {:foo [1 2 4], [0] :bar, :baz {42 []}}
postwalk
and prewalk
are effectively the same in this instance but the difference can matter if your replacement function adds/removes sub-entries.
The specter library might also interest you - its transform
, select
and so on allow you to approach get-in
type jobs from a slightly different direction and with that data structure agnosticism.
Upvotes: 1