【问题标题】:Clojure: Vector is not immutableClojure:向量不是不可变的
【发布时间】:2018-11-17 00:28:47
【问题描述】:

我遇到了一个问题,即不变性突然不适用于我的向量。我想知道是否有一种方法可以创建给定集合的新的、不可变的向量副本。

Clojuredocs 建议“克隆”,但这给了我一个错误,指出没有这种方法。

(defn stripSame [word wordList]
  (def setVec (into #{} wordList))
  (def wordSet word)
  (def wordVec (into #{} [wordSet]))
  (def diffSet (set/difference setVec wordVec))
  (def diffVec (into [] diffSet))
  diffVec) 


(defn findInsOuts [word passList]
  (def wordList (stripSame word passList))
  (println word wordList)
  (def endLetter (subs word (dec (count word))))
  (def startLetter  (subs word 0 1))
  (println startLetter endLetter)
  (def outs (filter (partial starts endLetter) wordList))
  (def ins (filter (partial ends startLetter) wordList))
  ;(println ins outs)
  (def indexes [ (count ins) (count outs)])
  indexes)

(defn findAll [passList]
  (def wordList   (into [] passList) ))
  (println wordList)
  (loop [n 0 indexList []]
    (println  "In here" (get wordList n) wordList)
    (if (< n (count wordList))
      (do
        (def testList wordList)
        (def indexes (findInsOuts (get wordList n) testList))
        (println (get wordList n) indexes)
        (recur (inc n) (conj indexList [(get wordList n) indexes]))))))

passList 是这样的单词列表(很好笑),然后将其转换为向量。

所以基本上 findAll 调用 findInsOuts ,它遍历列表中的每个单词并查看有多少其他单词以它的最后一个字母开头,但它首先从向量中删除搜索词,然后再执行一些功能以防止重复。问题在于,不知何故,这个向量实际上是可变的,所以 findAll also 中的向量副本永久删除了该值。

当我尝试创建一个新向量然后对该向量执行操作时,仍然会发生同样的事情,这意味着它们被别名/共享相同的内存位置。

如何创建一个实际上不可变的新向量以供使用?

感谢任何帮助

【问题讨论】:

    标签: vector clojure


    【解决方案1】:

    恐怕您的代码充满了误解。首先,不要在defn 中使用def。请改用let。这会将您的第一个函数变成 ...

    (defn stripSame [word wordList]
      (let [setVec (into #{} wordList)
            wordSet word
            wordVec (into #{} [wordSet])
            diffSet (clojure.set/difference setVec wordVec)
            diffVec (into [] diffSet)]
        diffVec))
    

    例如,

    => (stripSame 2 [1 2 :buckle-my-shoe])
    [1 :buckle-my-shoe]
    

    函数可以简化为...

    (defn stripSame [word wordList]
      (vec (disj (set wordList) word)))
    

    ...或者,使用线程宏,到...

    (defn stripSame [word wordList]
      (-> wordList set (disj word) vec))
    

    我认为该函数不会像您认为的那样做,因为它并不总是保留向量中元素的顺序。


    如果我是你,我会在this page 上完成一些社区教程。那里也提到了几本好书。一旦你掌握了语言的习语,你会发现你在这里尝试做的事情变得更加清晰和容易。

    【讨论】:

    • 应该补充一点,def 进行全局变量绑定,这就是函数相互破坏数据的原因。
    猜你喜欢
    • 2013-04-06
    • 2019-06-20
    • 2014-02-18
    • 1970-01-01
    • 2022-11-30
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    相关资源
    最近更新 更多