首页 > 解决方案 > lang.LazySeq 不能转换为 IPersistantVector

问题描述

在学习 Clojure 的过程中。

我有一个从牌组中随机抽取一张牌的功能

(defn draw-random-card
  [cards]
  (let [card (rand-nth cards)
        index (.indexOf cards card)]
    {:card card :remaining-cards (concat (subvec cards 0 index)
                                         (subvec cards (inc index)))}))

运行它:

(draw-random-card ["Ace" 2 3 4 5 6 7 8 9 10 "Jack" "Queen" "King"])
=> {:card 4, :remaining-cards ("Ace" 2 3 5 6 7 8 9 10 "Jack" "Queen" "King")}

我想叫它两次并拿出 2 张牌,但它第二次叫它,它会通过第一次叫它减少的牌组。

最后,我想要两张卡和简化的套牌以供以后使用。

我原以为我可以做类似的事情:

(def full-deck ["Ace" 2 3 4 5 6 7 8 9 10 "Jack" "Queen" "King"])
(let [first-draw (draw-random-card full-deck)
       first-card (:drawn-card first-draw)
       second-draw (draw-random-card (:remaining-cards first-draw)) 
       second-card (:drawn-card second-draw)
       remaining-deck (:remaining-cards second-draw)]
   (println "First card: " first-card)
   (println "Second card: " second-card)
   (println "Remaining deck:" remaining-deck))

但是,当我得到错误时,我显然在这里做了一些愚蠢的事情:

Execution error (ClassCastException) at aceyducey.core/draw-random-card (form-init3789790823166246683.clj:5).
clojure.lang.LazySeq cannot be cast to clojure.lang.IPersistentVector

我认为问题出在一线

second-draw (draw-random-card (:remaining-cards first-draw))]

因为剩余卡不是向量?

意思是

concat (subvec cards 0 index)
           (subvec cards (inc index)))}))

不是返回向量吗?而是一个懒惰的序列???

但在这一点上,我迷路了。

帮助!

标签: clojure

解决方案


@amalloy 提出了一个很好的观点: Clojure 内置函数 shuffle可能是您想要的:

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test) )

(def cards [:ace 2 3 4 5 6 7 8 9 10 :jack :queen :king] )

(dotest
  (dotimes [i 3]
    (spyx (shuffle cards))))

=>

Testing tst.demo.core
(shuffle cards) => [:king :jack 6 2 9 10 :ace 4 8 5 3 :queen 7]
(shuffle cards) => [2 :jack 7 9 :queen 8 5 3 4 :ace 10 :king 6]
(shuffle cards) => [7 :queen :jack 4 3 :king 6 :ace 2 10 5 8 9]

Clojure CheatSheet提供了这些以及更多内容。请务必将其添加为书签,并始终保持浏览器选项卡打开。


推荐阅读