2017-03-17 71 views
1

的内部向量我有图的载体,其看起来像这样替换地图

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

换句话说,正的地图的矢量,与所述键中的一个也正在的载体。

我想用外部矢量的所有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]}] 

换言之从内部向量挑选出一个范围内的元素,同时保持数据结构否则完好无损。

回答

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

您可以使用mapv映射在向量的元素,使用update-in然后再做另一mapv的载体来提取想要索引更新:key3

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

对于许多数据操作,像update-in和mapv这样的核心功能在这类问题上做得很好。有几种方法可以巧妙地使用它们,取回一个序列而不是一个向量。有时候,代码也可能不太现实。

spectre库的建立是为了使这种数据处理方便,intuative的:

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给出了一个更完整(和斟酌)的介绍。