提供数据:
data = [
{"id":14, "sort":1, "content":"9", foo: "2022"},
{"id":14, "sort":4, "content":"5", foo: "2022"},
{"id":14, "sort":2, "content":"1", foo: "2022"},
{"id":14, "sort":3, "content":"0", foo: "2022"},
{"id":15, "sort":4, "content":"4", foo: "2888"},
{"id":15, "sort":2, "content":"1", foo: "2888"},
{"id":15, "sort":1, "content":"3", foo: "2888"},
{"id":15, "sort":3, "content":"3", foo: "2888"},
{"id":16, "sort":1, "content":"8", foo: "3112"},
{"id":16, "sort":3, "content":"4", foo: "3112"},
{"id":16, "sort":2, "content":"4", foo: "3112"},
{"id":16, "sort":4, "content":"9", foo: "3112"}
]
将由其sort
和ids
连接的内容分配给:
formatted = data.group_by { |d| d[:id]}.transform_values do |value_array|
value_array.sort_by { |b| b[:sort] }
.map { |c| c[:content] }.join
end
puts formatted
#=> {14=>"9105", 15=>"3134", 16=>"8449"}
我知道foo
内部存在value_array
,但想知道如何将foo
包含在formatted
变量中,以便我可以通过它映射以获得所需的输出还是有可能?
所需的输出:
[
{"id":14, "concated_value":"9105", foo: "2022"},
{"id":15, "concated_value":"3134", foo: "2888"},
{"id":16, "concated_value":"8449", foo: "3112"}
]
答案 0 :(得分:4)
由于:foo
对于:id
是唯一的。您可以按照以下步骤进行操作:
data.group_by {|h| h[:id]}.map do |_,sa|
sa.map(&:dup).sort_by {|h| h.delete(:sort) }.reduce do |m,h|
m.merge(h) {|key,old,new| key == :content ? old + new : old }
end.tap {|h| h[:concated_value] = h.delete(:content) }
end
#=> [
# {"id":14, foo: "2022", "concated_value":"9105"},
# {"id":15, foo: "2888", "concated_value":"3134"},
# {"id":16, foo: "3112", "concated_value":"8449"}
# ]
group_by {|h| h[:id]}
map(&:dup)
.sort_by {|h| h.delete(:sort) }
m.merge(h) {|key,old,new| key == :content ? old + new : old }
content
的密钥更改为concated_value
tap {|h| h[:concated_value] = h.delete(:content) }
答案 1 :(得分:2)
我们可以使用value_array中的第一个值来获取我们的:id和:foo值
::ng-deep .mat-progress-bar[dir='rtl'],
:host-context([dir='rtl']) ::ng-deep .mat-progress-bar {
transform: none;
}
答案 2 :(得分:2)
我认为这对于reduce
是一个很好的用例,因为在分组之后,您需要首先从[ID, VALUES]
除去结果group_by
数组中的ID,然后返回简化版本VALUES
部分中的内容-无需任何ActiveSupport
等依赖项就可以完成所有操作。
data
.group_by{ |d| d[:id] } # Get an array of [ID, [VALUES]]
.reduce([]) do |a, v| # Reduce it into a new empty array
# Append a new hash to the new array
a << {
id: v[1].first[:id], # Just take the ID of the first entry
foo: v[1].first[:foo], # Dito for foo
concatenated: v[1]
.sort_by{ |s| s[:sort] } # now sort all hashes by its sort key
.collect{ |s| s[:content] } # collect the content
.join # and merge it into a string
}
end
输出:
[{:id=>14, :foo=>"2022", :concatenated=>"9105"},
{:id=>15, :foo=>"2888", :concatenated=>"3134"},
{:id=>16, :foo=>"3112", :concatenated=>"8449"}]
编辑
当我开始编写先前的解决方案时,我想到了其他方法,reduce
并不是真正必要的,因为group_by
之后的数组大小不会改变,因此{{1 }}就足够了。
但是在重写代码时,我在想用所有键创建一个新的散列并从map
中的第一个散列中复制所有值是一件很麻烦的事情,因此,这样做很容易拒绝开销键:
VALUES
输出
keys_to_ignore = [:sort, :content]
data
.group_by{ |d| d[:id] } # Get an array of [ID, [VALUES]]
.map do |v|
v[1]
.first # Take the first hash from [VALUES]
.merge({'concatenated': v[1] # Insert the concatenated values
.sort_by{ |s| s[:sort] } # now sort all hashes by its sort key
.collect{ |s| s[:content] } # collect the content
.join # and merge it into a string
})
.select { |k, _| !keys_to_ignore.include? k }
end
在线演示here
答案 3 :(得分:1)
即使没有Rails,也可以使用:
$irb> formatted = []
$irb> data.sort_by!{|a| a[:sort]}.map {|z| z[:id]}.uniq.each_with_index { |id, index| formatted << {id: id, concated_value: data.map{|c| (c[:id] == id ? c[:content] : nil)}.join, foo: data[index][:foo]}}
$irb> formatted
[{:id=>14, :concated_value=>"9105", :foo=>"2022"},
{:id=>15, :concated_value=>"3134", :foo=>"2888"},
{:id=>16, :concated_value=>"8449", :foo=>"3112"}]
答案 4 :(得分:-1)
data.sort_by { |h| h[:sort] }.
each_with_object({}) do |g,h| h.update(g[:id]=>{ id: g[:id],
concatenated_value: g[:content].to_s, foo: g[:foo] }) { |_,o,n|
o.merge(concatenated_value: o[:concatenated_value]+n[:concatenated_value]) }
end.values
#=> [{:id=>14, :concatenated_value=>"9105", :foo=>"2022"},
# {:id=>15, :concatenated_value=>"3134", :foo=>"2888"},
# {:id=>16, :concatenated_value=>"8449", :foo=>"3112"}]
这使用Hash#update(也称为merge!
)的形式,该形式采用一个块来确定合并的两个哈希中都存在的键的值(此处为:id
的值) 。有关三个块变量(此处为_
,o
和n
的描述,请参见文档。
请注意,values
(最后)的接收者如下。
{ 14=>{ :id=>14, :concatenated_value=>"9105", :foo=>"2022" },
15=>{ :id=>15, :concatenated_value=>"3134", :foo=>"2888" },
16=>{ :id=>16, :concatenated_value=>"8449", :foo=>"3112" } }