我必须承认,这仍然是我是一个新手的地方。 我经常发现,如果我在Clojure文档中搜索,我会找到我正在寻找的功能。 ;)
但我对此感到紧张,但也许我可能会走运。
我有一个纸牌游戏。 每个玩家手里有一手1-9张牌。
这些牌通过抽奖从他们的牌组顶部一次放到他们手中 1 张牌。
玩家所要求的是能够将无组织的手牌或未分类的手牌重新组织起来。
我提供了一个解决方案"命令窗口中像/re-order 31487652 这样的命令怎么样,它可以发出函数(不用担心命令,它只是排序功能(。
这样做的目标是将手中的每张牌12345678并将顺序更改为他们提供的新订单,即31487652。
数据采用以下格式:
(:hand player)
[{:name : "Troll", :_id : 39485723},
{:name : "Ranger", :_id : 87463293},
{:name : "Archer", :_id : 78462721},
{:name : "Orc", :_id : 12346732},
{:name : "Orc", :_id : 13445130},
{:name : "Spell", :_id : 23429900},
{:name : "Dagger", :_id : 44573321}]
我唯一的问题是,我可以使用传统的编程语言来考虑这个问题,我的意思是很容易,您只需将数据复制到另一个数组,哈哈,但我的意思是我们不喜欢clojure吗?...
但我想把事情保持在纯粹的clojure意识形态中,并学习如何做这样的事情。 我的意思是,如果只是"使用这个函数",我想这很好,但我不想创建一个原子,除非是强制性的,但我认为情况并非如此。
如果有人能帮助我开始思考一种使用 clojure 解决这个问题的方法,那就太棒了!
感谢您的任何帮助/建议/答案...
附录 #1
(defn vec-order [n]
(into [] (if (pos? n)
(conj (vec-order (quot n 10)) (mod n 10) )
[])))
(defn new-index [index new-order] (.indexOf new-order (inc index)))
(defn re-order [state side value]
(println (get-in @state [side :hand]))
(update @state [side :hand]
(fn [hand]
(->> hand
(map-indexed (fn [index card] [(new-index index (vec-order value)) card]))
(sort-by first)
(mapv second))))
(println (get-in @state [side :hand])))
所以这是我当前的代码,提取数据。 有一个巨大的@state,玩家所在的一侧。 我使用:
(println (get-in @state [side :hand]))
查看执行defn之前和之后的数据,但我没有得到任何变化。 为简单起见,向量21436587为 [2 1 4 3 6 5 8 7]。
但是我错过了一些东西,因为我什至运行了/re-order 12345678以确保东西没有移动,我只是没有看到东西。 但是什么都没有...
谢谢你,绝对让我走到这一步。
如果你有所需的元素顺序作为向量,你可以通过一个函数来sort-by
,返回该向量中卡的索引:
(let [cards [1 2 3 4 5 6 7 8]
my-order [3 1 4 8 7 6 5 2]]
(sort-by #(.indexOf my-order %) cards))
;; => (3 1 4 8 7 6 5 2)
因此,注意的第一个功能将是更新,如果我们这样调用它,这将允许我们返回一个新玩家,并应用一个函数。
(update player :hand (fn [hand] ... ))
一旦我们有了这个基本结构,下一个帮助我们的函数就是 map-indexed,这将允许我们将当前手牌与新的排序排序索引配对。
从那里,我们将能够按索引排序,最后 mapv 检索卡片。
因此,最终结构将如下所示:
(defn sort-hand [player new-order]
(update
player
:hand
(fn [hand]
(->> hand
(map-indexed (fn [index card] [(new-index index new-order) card]))
(sort-by first)
(mapv second)))))
为此,预计new-order
是一个类似于[3 1 4 8 7 6 5 2]
的向量
至于new-index
的解决方案,
我们可以像这样使用
.indexOf
(defn new-index [index new-order] (.indexOf new-order (inc index)))
在您的帮助下:
(defn vec-order [n]
(into [] (if (pos? n)
(conj (vec-order (quot n 10)) (mod n 10) )
[])))
(defn new-index [new-order index] (.indexOf new-order (inc index)))
(defn re-order [state side value]
(swap! state update-in [side :hand]
(fn [hand]
(->> hand
(map-indexed (fn [index card] [(new-index (vec-order value) index) card]))
(sort-by first)
(mapv second)))))
有效!! 100%