将矢量映射转换为 Clojure 中的列矢量
Convert map of vectors to vectors of columns in Clojure
我有一个地图集合(或列表、序列或向量),如下所示:
{ :name "Bob", :data [32 11 180] }
{ :name "Joe", :data [ 4 8 30] }
{ :name "Sue", :data [10 9 40] }
我想创建新的向量,其中包含与描述数据的键关联的向量 "columns" 中的数据,如下所示:
{ :ages [32 4 10], :shoe-sizes [11 8 9], :weights [180 30 40] }
实际上,一个简单的向量列表可能就足够了,即:
[32 4 10] [11 8 9] [180 30 40]
如果better/easier将原始列表做成一个vector,就可以了;最简单的。
你可以像这样使用 reduce:
(def data [{ :name "Bob", :data [32 11 180] }
{ :name "Joe", :data [ 4 8 30] }
{ :name "Sue", :data [10 9 40] }])
(reduce
(fn [acc {[age shoe-size weight] :data}]
(-> acc
(update-in [:ages] conj age)
(update-in [:shoe-sizes] conj shoe-size)
(update-in [:weights] conj weight)))
{}
data)
Returns 像这样:
{:weights (40 30 180), :shoe-sizes (9 8 11), :ages (10 4 32)}
我认为这段代码最有趣的部分是使用嵌套解构来获取键:{[age shoe-size weight] :data}
给出
(def records
[{:name "Bob" :data [32 11 180]}
{:name "Joe" :data [ 4 8 30]}
{:name "Sue" :data [10 9 40]}])
您可以进行下一步转换以获得所需的结果:
(->> records
(map :data) ; extract :data vectors
; => ([32 11 180] [4 8 30] [10 9 40])
(apply map vector) ; transpose
; => ([32 4 10] [11 8 9] [180 30 40])
(zipmap [:ages :shoe-sizes :weights])) ; make map
; => {:weights [180 30 40], :shoe-sizes [11 8 9], :ages [32 4 10]}
没有注释看起来更干净一些:
(->> records
(map :data)
(apply map vector)
(zipmap [:ages :shoe-sizes :weights]))
没有 threading 宏相当于更冗长:
(let [extracted (map :data records)
transposed (apply map vector extracted)
result (zipmap [:ages :shoe-sizes :weights] transposed)]
result)
我有一个地图集合(或列表、序列或向量),如下所示:
{ :name "Bob", :data [32 11 180] }
{ :name "Joe", :data [ 4 8 30] }
{ :name "Sue", :data [10 9 40] }
我想创建新的向量,其中包含与描述数据的键关联的向量 "columns" 中的数据,如下所示:
{ :ages [32 4 10], :shoe-sizes [11 8 9], :weights [180 30 40] }
实际上,一个简单的向量列表可能就足够了,即:
[32 4 10] [11 8 9] [180 30 40]
如果better/easier将原始列表做成一个vector,就可以了;最简单的。
你可以像这样使用 reduce:
(def data [{ :name "Bob", :data [32 11 180] }
{ :name "Joe", :data [ 4 8 30] }
{ :name "Sue", :data [10 9 40] }])
(reduce
(fn [acc {[age shoe-size weight] :data}]
(-> acc
(update-in [:ages] conj age)
(update-in [:shoe-sizes] conj shoe-size)
(update-in [:weights] conj weight)))
{}
data)
Returns 像这样:
{:weights (40 30 180), :shoe-sizes (9 8 11), :ages (10 4 32)}
我认为这段代码最有趣的部分是使用嵌套解构来获取键:{[age shoe-size weight] :data}
给出
(def records
[{:name "Bob" :data [32 11 180]}
{:name "Joe" :data [ 4 8 30]}
{:name "Sue" :data [10 9 40]}])
您可以进行下一步转换以获得所需的结果:
(->> records
(map :data) ; extract :data vectors
; => ([32 11 180] [4 8 30] [10 9 40])
(apply map vector) ; transpose
; => ([32 4 10] [11 8 9] [180 30 40])
(zipmap [:ages :shoe-sizes :weights])) ; make map
; => {:weights [180 30 40], :shoe-sizes [11 8 9], :ages [32 4 10]}
没有注释看起来更干净一些:
(->> records
(map :data)
(apply map vector)
(zipmap [:ages :shoe-sizes :weights]))
没有 threading 宏相当于更冗长:
(let [extracted (map :data records)
transposed (apply map vector extracted)
result (zipmap [:ages :shoe-sizes :weights] transposed)]
result)