将2个值合并到返回列表中的方法?

时间:2017-02-11 17:53:23

标签: recursion clojure artificial-intelligence

    (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
      (conj (returnLoc (rest obj-data) super-cat)
            (nth (first obj-data) 3))
      ;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)
      )
    ())
  )

正如您所看到的,一旦代码找到匹配,我将返回obj数据的第3个值,是否有一种方法可以让obj-data的第二个值每次返回第3个,并且然后在其末尾添加一个分隔符,

它当前返回一个项目(水果/代理)的位置,但我希望它返回特定的项目和位置。

所以看起来像:

(returnLoc obj-data 'agent)

返回:

=>(hallway bedroom)

理想情况下,我希望它返回:

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

有没有人有解决方法如何做到这一点?

3 个答案:

答案 0 :(得分:3)

如果你的解决方案更加惯用,你的直接问题就会消失:

  1. obj-data的每个元素表示为地图(或记录),而不是列表。
  2. 识别returnLoc计算的模式。
  3. <强> 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]))))
    

答案 1 :(得分:1)

conj需要将多个元素添加到集合中:

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

答案 2 :(得分:-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)
      )
    ())
  )