Clojure 重排序函数
Clojure re-order function
我必须承认这仍然是我 clojure 新手的地方。我经常发现,如果我在 Clojure 文档中搜索,我会找到我正在寻找的函数。 ;)
但我对这个很紧张,但也许我会走运。
我有一个纸牌游戏。每个玩家手中有 1-9 张牌。
通过抽牌从牌组顶开始将牌一次放入一张牌。
玩家要求的是能够将 UNORGANIZED 手牌或 UNSORTED 手牌带到那里并重新组织他们的手牌。
我提供了一个解决方案“在命令 window 中使用 /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 意识形态,并学习如何做这样的事情。我的意思是,如果它只是 "Use this function",我想那很好,但我不想创建一个原子,除非是强制性的,但我认为情况并非如此。
如果有人可以帮助我开始思考使用 clojure 解决这个问题的方法,那就太棒了!
感谢任何 help/advice/answer...
附录 #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执行前后的数据,但我没有得到任何变化。为简单起见,向量为 [2 1 4 3 6 5 8 7].
中的 21436587
但我遗漏了一些东西,因为我什至 运行 /重新订购 12345678 以确保东西没有移动,我只是没有看到东西。但是什么都没有...
谢谢你,让我走到这一步。
因此,注意的第一个函数将是 update,这将使我们能够 return 一个新玩家,如果我们这样调用它,它会应用一个函数。
(update player :hand (fn [hand] ... ))
一旦我们有了这个基本结构,下一个对我们有帮助的函数是map-indexed,它将允许我们将当前手牌与新的排序索引配对。
从那里,我们将能够sort-by the index, and finally 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)))
如果您将所需的元素顺序作为向量,您可以 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)
在您的帮助下:
(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%
我必须承认这仍然是我 clojure 新手的地方。我经常发现,如果我在 Clojure 文档中搜索,我会找到我正在寻找的函数。 ;)
但我对这个很紧张,但也许我会走运。
我有一个纸牌游戏。每个玩家手中有 1-9 张牌。
通过抽牌从牌组顶开始将牌一次放入一张牌。
玩家要求的是能够将 UNORGANIZED 手牌或 UNSORTED 手牌带到那里并重新组织他们的手牌。
我提供了一个解决方案“在命令 window 中使用 /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 意识形态,并学习如何做这样的事情。我的意思是,如果它只是 "Use this function",我想那很好,但我不想创建一个原子,除非是强制性的,但我认为情况并非如此。
如果有人可以帮助我开始思考使用 clojure 解决这个问题的方法,那就太棒了!
感谢任何 help/advice/answer...
附录 #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执行前后的数据,但我没有得到任何变化。为简单起见,向量为 [2 1 4 3 6 5 8 7].
中的 21436587但我遗漏了一些东西,因为我什至 运行 /重新订购 12345678 以确保东西没有移动,我只是没有看到东西。但是什么都没有...
谢谢你,让我走到这一步。
因此,注意的第一个函数将是 update,这将使我们能够 return 一个新玩家,如果我们这样调用它,它会应用一个函数。
(update player :hand (fn [hand] ... ))
一旦我们有了这个基本结构,下一个对我们有帮助的函数是map-indexed,它将允许我们将当前手牌与新的排序索引配对。
从那里,我们将能够sort-by the index, and finally 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)))
如果您将所需的元素顺序作为向量,您可以 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)
在您的帮助下:
(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%