Clojure重新排序功能

时间:2018-09-29 18:32:01

标签: sorting clojure reorganize

我必须承认,我仍然是Clojure新手。我经常发现,如果我在Clojure Docs中搜索,就会找到所需的功能。 ;)

但是我对此很紧张,但是也许我会很幸运。

我有一个纸牌游戏。每个玩家手中的手牌范围从1到9张不等。

通过抽奖,从卡组的顶部一次将一张卡放入手中。

玩家要求的是能够握住未组织的手或未组织的手并重新握起手的能力。

我提供了一种解决方案,“如何在命令窗口中执行类似/ 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之前和之后查看数据,但是我没有任何改变。为简单起见,矢量为[21 4587]成[2 1 4 3 6 5 8 7]。

但是我丢失了一些东西,因为我什至运行/ re-order 12345678来确保没有移动任何东西并且我只是看不到东西。但是什么都没有...

非常感谢您,让我走了这么远。

3 个答案:

答案 0 :(得分:3)

如果您具有所需的元素顺序作为矢量,则可以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)

答案 1 :(得分:1)

因此,音符的第一个功能将是update,如果我们这样调用它,它将允许我们返回一个具有适用于手牌的功能的新玩家。

(update player :hand (fn [hand] ... ))

一旦有了基本结构,下一个对我们有帮助的功能就是map-indexed,它将使我们能够将当前的手与新的排序索引配对。

从那里,我们将能够sort-by索引,最后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)))

答案 2 :(得分:0)

在您的帮助下:

(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%