Если вы сделаете ваше решение более идиоматических, ваши насущные проблемы исчезают:
- Представьте каждый элемент
obj-data
в качестве карты (или записи), а не как список.
- Присвоить шаблон вычисления
returnLoc
.
1. Представьте каждый элемент obj-data
как карту (или запись), а не как список.
Ваше искомое решение может затем быть
[{:who 'Tom, :where 'hallway} {:who 'Jerry, :where 'bedroom}]
Это вполне читаема, поэтому вам не нужно спешить, чтобы перевести его в плоский текст.
2. Распознать шаблон вычисления returnLoc
.
Что делает returnLoc
?
- Он выбирает элементы OBJ-данных, которые имеют особое
characeristic: их стоимость :where
является super-cat
. Это операция filter
.
- Он извлекает атрибут
:who
из всех таких элементов. Это операция map
.
Ваш returnLoc
функция может затем быть
(defn returnLoc [obj-data super-cat]
(map
:who
(filter
#(= (:where %) super-cat)
obj-data)))
... или, используя макрос продевал,
(defn returnLoc [obj-data super-cat]
(->> obj-data
(filter #(= (:where %) super-cat))
(map :who)))
- Ключевые слова
:who
и :where
используются в качестве функций доступа.
- Эти версии поддерживают порядок элементов в
obj-data
. Ваш код меняет его.
Поскольку вы хотите сохранить оба :who
и :where
поля, то почему бы не просто вернуть всю карту/запись:
(defn returnLoc [obj-data super-cat]
(filter
#(= (:where %) super-cat)
obj-data))
Это экономит работу, так как неизменная карта возвращается по ссылке. Не нужно строить новую карту.
Если вы решили избавиться от других полей, используйте select-keys
:
(defn returnLoc [obj-data super-cat]
(->> obj-data
(filter #(= (:where %) super-cat))
(map #(select-keys % [:who :where]))))