【问题标题】:Replace vector inside of map替换地图内的矢量
【发布时间】:2017-03-18 04:16:17
【问题描述】:

我有一个看起来像这样的地图矢量

[{:key1 val1 :key2 val2 :key3 [vector]}
 {:key1 val1 :key2 val2 :key3 [vector]}]

换句话说,一个包含 n 个映射的向量,其中一个键也是一个向量。

我想用一个新的向量替换 :key3 向量,在外向量的所有 n 个映射中,但我想不出一个好方法。

作为一个额外的问题,我还想创建一个具有相同结构的新地图,但内部向量包含选定范围的元素。所以例如从这个

[{:key1 val1 :key2 val2 :key3 [v1 v2 v3 v4]}
 {:key1 val2 :key2 val2 :key3 [v1 v2 v3 v4]}]

到这里:

[{:key1 val1 :key2 val2 :key3 [v2 v3]}
 {:key1 val2 :key2 val2 :key3 [v2 v3]}]  

换句话说,从内部向量中挑选出一系列元素,同时保持数据结构不变。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    您可以使用mapv 映射向量的元素,使用update-in 更新:key3,然后对向量执行另一个mapv 以提取您想要的索引:

    (def m [{:key1 val1 :key2 val2 :key3 [:a :b :c :d]}
            {:key1 val1 :key2 val2 :key3 [:a :b :c :d]}])
    
    (mapv #(update-in % [:key3] (fn [v] (mapv v [1 2]))) m)
    

    【讨论】:

      【解决方案2】:

      对于很多数据操作,像update-in和mapv这样的核心函数在这类问题上做得很好。有几种方法可以巧妙地错误地使用它们并返回一个序列而不是一个向量。代码有时也会变得有点笨拙。

      spectre 库的创建是为了让这种数据操作变得简单而直观:

      hello.core> (require '[com.rpl.specter :refer :all])
      nil
      
      hello.core> (def data '[{:key1 val1 :key2 val2 :key3 [vector]}
                              {:key1 val1 :key2 val2 :key3 [vector]}])
      #'hello.core/data
      
      hello.core> (setval [ALL :key3] '[v2 v3] data)
      [{:key1 val1, :key2 val2, :key3 [v2 v3]} 
       {:key1 val1, :key2 val2, :key3 [v2 v3]}]
      

      它还尝试对每个转换使用最有效的更新方法。 这个article 给出了更完整(和自以为是)的介绍。

      【讨论】:

        【解决方案3】:
        (def m [{:key1 val1 :key2 val2 :key3 [:a :b :c :d]}
                {:key1 val1 :key2 val2 :key3 [:a :b :c :d]}])
        
        (mapv #(update % :key3 (fn [v] (mapv v [1 2]))) m)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-17
          • 2018-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-25
          • 1970-01-01
          相关资源
          最近更新 更多