【问题标题】:Fill a Clojure vector填充 Clojure 向量
【发布时间】:2017-01-07 16:06:22
【问题描述】:

我正在尝试用地图中的值填充 Clojure 向量。 我在地图中有另一个特定键的向量存储我需要的值。 我需要迭代 key-vec,从地图中获取值并将它们存储在另一个向量中。

我尝试过使用循环+递归:

(let [keys-vec (:keys-vec item)
      my-map (:my-map item)]

   (loop [newV []
          i 0]
      (if (< i (count keys-vec))
        (recur
          (conj newV (get my-map (get keys-vec i)))
          (inc i))

         newV)))

它奏效了。 但我知道 Clojure 以其简约/高效的代码编写风格而闻名,我想知道是否有更好的方法。

有什么想法吗?

【问题讨论】:

  • 您能具体说明您要达到的目标吗? (def new-vector existing-vector)不解决问题吗?
  • 我相信在 Clojure 中使用 loop 和元素的索引来迭代向量接近于反模式,因为 Clojure 的集合是不可变的和持久的。相反,我们鼓励您使用归约函数。完成任务的惯用方式就是(vals (select-keys my-map keys-vec))
  • 你说得对,它有效。谢谢!

标签: arrays vector clojure fill idioms


【解决方案1】:

使用Alan Thompson's example

(def my-map {:a 1 :b 2 :c 3})
(def my-keys [:a :b])

...一个简单快速的解决方案是

(mapv my-map my-keys)
;[1 2]

另一种选择

(vals (select-keys my-map my-keys))
;(2 1)

...可能不会(在这种情况下也不会)维持my-keys 给出的顺序。

【讨论】:

    【解决方案2】:

    您希望select-keys 函数仅从您的地图中提取感兴趣的键。见:http://clojuredocs.org/clojure.core/select-keys

    然后,使用vals 函数从过滤后的映射中提取所有值:

    > (def my-map {:a 1 :b 2 :c 3})
    > (def my-keys [:a :b])
    > (select-keys my-map my-keys)
    {:a 1, :b 2}
    
    > (def filtered-map (select-keys my-map my-keys))
    > filtered-map
    {:a 1, :b 2}
    
    > (vals filtered-map)
    (1 2)
    

    您应该始终保持浏览器选项卡对 Clojure 备忘单打开。它对于找到您想要的功能非常宝贵。继续反复研究它,因为你会在很多年里不断发现新事物。这是我最喜欢的版本:

    http://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip-cdocs-summary.html

    【讨论】:

      【解决方案3】:

      我想说,最惯用的方法是使用原始向量。我看不出有任何理由明确克隆不可变数据结构。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-10
        • 2014-11-21
        • 2020-07-07
        • 1970-01-01
        • 2020-05-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多