【发布时间】:2016-04-24 23:32:20
【问题描述】:
我有两张地图:
(def look {"directions" :look
"look" :look
"examine room" :look
})
(def quit {"exit game" :quit
"quit game" :quit
"exit" :quit
"quit" :quit
})
通过以下方式合并到一张地图中:
(defn actions [] (merge look quit))
然后我尝试将其结果(这是一个哈希映射)关联到另一个映射的值:
(assoc {} :1 actions)
但不是预期的结果应该是:
{1: {"directions" :look, "look" :look ...
我收到了
{:1 #object[fun_pro.core$actions 0x20a8027b "fun_pro.core$actions@20a8027b"]}
据我所知,这是对动作对象的引用。
我应该怎么做才能收到预期的结果?我也尝试过使用 unquote-splicing,但我还不够先进,无法使用宏并且无法使其工作。
编辑1:
好的,看来我找到了解决方案。我应该使用(def actions...),而不是使用(defn actions...)。
EDIT2:
澄清我为什么使用这样的结构。
正如我在下面的评论中所说,我将使用此地图将其与用户提供的答案进行比较,以找到要使用的命令。例如,如果用户键入“显示路线”,它将触发函数根据关键字“路线”显示路线。如果用户根据关键字“look”和“examine room”询问“我环顾房间”或“我检查房间以找到路”,结果将是相同的。
这将通过首先将用户输入拆分为一组字符串并从我的地图(变成集合)中查找是否有带有键的常用词来完成。所以输入"show me directions"会被处理成集合#{"show" "me" "directions"}。然后我将使用clojure.set/intersection 来查找是否存在具有一组映射关键字的公共元素并根据结果触发函数(我已经为此编写了算法)。
当然,如果有更好的解决方案,我愿意接受任何建议。
【问题讨论】:
-
你的地图是倒退的。使用符号作为键,而不是作为值。根据您要执行的操作,地图甚至可能不是正确的选择。
-
@jmargolisvt 什么?为什么你会说他的地图是向后的,因为它将字符串映射到关键字?对他的数据的快速检查可以很清楚地知道他想要做什么。
-
@MarcinKruglik 既然您已经找到了解决方案,您能否将其发布为答案而不是问题的编辑?
-
@jmargolisvt 我将使用此地图将其与用户提供的答案进行比较,以找到要使用的命令。例如,如果用户键入“显示路线”,它将触发函数根据关键字“路线”显示路线。如果用户根据关键字“look”和“examine room”询问“我环顾房间”或“我检查房间以找到路”,结果将是相同的。这就是我使用字符串的原因。我尝试将 Lisp 讲师提供的代码实现到 Clojure 中。
-
@Elogent,当我说他想要做什么时,我并不是指他合并它们的直接目标。我的意思是,当他继续添加到动作列表中时,用字符串键控它们不会很有用。继续为每个添加一个 :quit 符号也不是理想的。我会使用嵌套地图并从字符串中制作一个向量。这样@MarcinKruglik,您可以简单地显示您的操作列表:
(-> :list-of-actions :action-name)。