Clojure重新排序功能



我必须承认,这仍然是我是一个新手的地方。 我经常发现,如果我在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%

最新更新