【发布时间】:2016-02-22 19:02:48
【问题描述】:
朋友们,
问这个问题我觉得非常愚蠢......但是,在为这个问题挣扎了一段时间之后,我决定另一双眼睛可能有助于阐明我的问题。
我正在尝试同时循环遍历两条记录和一个映射(我也可以将映射重写为记录,但我不需要),比较一些条目,如果条目匹配则更改值。我所拥有的与此类似:
编辑:这里试图具体描述我在做什么。然而,现在我想这也许不是最好的方法。
我正在尝试使用 clojure 为 AI 课程创建餐厅选择推理引擎。我对 clojure 的经验很少,但最初想创建一个名为“restaurant”的结构,以便我可以创建它的多个实例。我读到 clojure 中的结构已被弃用,因此改为使用记录。从文本文件中读取的餐厅和用户输入都存储为“餐厅”记录。
我从之前排序的文本文件数据库中读入相关餐厅的属性(名称、菜式、评级、位置、价格等),然后将它们放入向量中。
每个属性都有一个与其关联的权重,因此当用户输入搜索条件时,可以根据最有可能是权重最高的项目(例如,餐厅名称是最重要的项目,其次是美食类型,然后是评级等。)。因此,该记录还具有“相关性”属性。
(defrecord Restaurant [resturant-name cuisine
rating location
price relevance])
;stuff
;stuff
;stuff
(defn search
[restaurants user-input]
(def ordered-restaurants [])
(doseq [restaurant restaurants]
(let [restaurant-relevance-value 0]
(doseq [input user-input
attributes restaurant
attribute-weight weights]
(cond
(= input (val attributes))
(def restaurant-relevance-value (+ restaurant-relevance-value
(val attribute-weight)))))
(assoc restaurant :relevance restaurant-relevance-value)
(def ordered-restaurants (conj ordered-restaurants restaurant))))
(def ordered-restaurants (sort-by > (:relevance ordered-restaurants)))
ordered-restaurants)
;more stuff
;more stuff
;more stuff
(defn -main
[& args]
(def restaurant-data (process-file "resources/ResturantDatabase.txt"))
(let [input-values (Restaurant. "Italian" "1.0" "1.0" "$" "true"
"Casual" "None" "1")]
(println :resturant-name (nth (search restaurant-data input-values) 0))))
所以想法是每家餐厅都被迭代,并将属性值与用户的输入值进行比较。如果存在匹配,则将本地相关值变量添加到相关的权重值。之后将其放入向量中,排序并返回。然后可以将结果显示给用户。理想情况下,-main 中的示例将打印最相关餐厅的名称。
【问题讨论】:
-
我在理解什么样的任务需要您同时遍历多个地图时遇到了一些麻烦,考虑到地图的迭代顺序是未定义的,除非它们已排序。你能添加一个MCVE 你到底在做什么吗?
-
do-seq 用于副作用,这很少是您想要的,当然不是在您只是从现有集合构建新集合的情况下。
-
Clojure 映射和记录是不可变的。
(assoc restaurant :relevance restaurant-relevance-value)-assoc返回添加了:relevance键的新餐厅记录,返回值被忽略。
标签: foreach clojure hashmap records