2017-02-11 4 views
0

Как вы можете видеть, я возвращаю третье значение obj-данных, как только код нашел совпадение, есть способ, по которому я могу получить второе значение obj-данных, чтобы возвращаться с 3-м каждый раз , а затем добавьте разделитель на конец этого,Способ соединить 2 значения в возвращаемом списке?

В настоящее время он возвращает местоположение объекта (фрукты/агент), но я хочу, чтобы он возвращал конкретный элемент и местоположение.

Так это выглядит, как:

(returnLoc obj-data 'agent) 

возвращается:

=>(hallway bedroom) 

, где в идеале я хотел бы, чтобы вернуться:

=>(tom is in hallway | jerry is in bedroom) 

Кто-нибудь есть решение о том, как сделай это?

ответ

-1

Разобрался свое собственное решение, которое работает:

(def obj-data 
       '((apple#3 apple fruit kitchen) 
       (mango#5 mango fruit kitchen) 
       (tom cat agent hallway) 
       (jerry mouse agent bedroom) 
       (matthew JavaStudentMatthew student livesAtHome) 
       (tom NetworkStudentTom student newcastleHome) 
       (Nathan NetworkStudentNathan student middlesbroughHome) 
       (Jack NetworkStudentJack student kexgillHome) 
       )) 

(defn returnLoc [obj-data super-cat] 
    ;If the list passed through is not empty 
    (if-not (empty? obj-data) 
    ;If the super-category passed in (i.e. Fruit/Agent) is equal 
    ;to the Super-Category (the second object in the first row) 
    (if (= super-cat (nth (first obj-data) 2)) 
     ;Recurvisely goes through the same process as above, 
     ;To see if there is any other records in the list with the same super-cat 
     ;then finds the location of the object and conj[oin]'s that to the returned values 
     (cons (list (nth (first obj-data) 1) " is in " (nth (first obj-data) 3)) 
     (returnLoc (rest obj-data) super-cat)) 
     ;If the super-cat passed through is not equal, it does not add it to the list 
     ;And recursively goes back through to check if there are any other possible items to add to 
     ;the list. 
     (returnLoc (rest obj-data) super-cat) 
    ) 
    ()) 
) 
1

conj занимает больше, чем один элемент будет добавлен в коллекцию:

(conj '(on this list) 'elements 'two) 
; ==> (two elements on this list) 
3

Если вы сделаете ваше решение более идиоматических, ваши насущные проблемы исчезают:

  1. Представьте каждый элемент obj-data в качестве карты (или записи), а не как список.
  2. Присвоить шаблон вычисления 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])))) 
Смежные вопросы