替换地图内的矢量

时间:2017-03-17 16:38:29

标签: clojure

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

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

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

我想在外部向量的所有n个映射中用新向量替换:key3向量,但我无法找到一种好方法。

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

[{: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]}]  

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

3 个答案:

答案 0 :(得分:0)

您可以使用mapv映射向量的元素,使用:key3更新update-in,然后对向量执行另一个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)

答案 1 :(得分:0)

对于许多数据操作,像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给出了更完整(和见解)的介绍。

答案 2 :(得分:-1)

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