合并列表中的json元素

时间:2017-05-09 01:12:02

标签: json ruby merge

我目前正在寻找合并列表中的元素。这些元素如下所示。代码在Ruby中

[
{
   :id => 0,
   :value => ["titi"],
   :allow => true,
   :text => "titi"
},
{
   :id => 0,
   :value => ["tata"],
   :allow => true
   :text => "tata"
}, 
{
   :id => 1,
   :value => ["blabla"],
   :allow => true,
   :text => "blabla"
}, 
{
   :id => 2,
   :value => ["ok"],
   :allow => true,
   :text => "ok"
}, 
{
   :id => 2,
   :value => ["ko"],
   :allow => true,
   :text => "ko"
}
]

我的目标是根据相同的" id"合并字段值。得到类似的东西:

[
{
   :id => 0,
   :value => ["titi", "tata"],
   :allow => true,
   :text => "titi, tata"
},
{
   :id => 1,
   :value => ["blabla"],
   :allow => true
   :text => "blabla"
}, 
{
   :id => 2,
   :value => ["ok", "ko"],
   :allow => true,
   :text => "ok, ko"
}
]

我曾尝试使用list.map并对其进行解析,但它无效。

根据下面的答案,我试图添加文本字段,但它没能很好地完成

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

使用Enumerable#group_by,您可以按给定块的结果对集合进行分组:

[1, 2, -1, 3, -3].group_by { |i| i.abs }
# => {1=>[1, -1], 2=>[2], 3=>[3, -3]}
[1, 2, -1, 3, -3].group_by { |i| i.abs }.values
# => [[1, -1], [2], [3, -3]]

通过组合分组集合,您将得到您想要的内容

ary = [
  { id: 0, value: ["titi"],   allow: true },
  { id: 0, value: ["tata"],   allow: true }, 
  { id: 1, value: ["blabla"], allow: true }, 
  { id: 2, value: ["ok"],     allow: true }, 
  { id: 2, value: ["ko"],     allow: true }
]

ary.group_by { |h| h[:id] }.values.map { |hs|
  hs.inject { |h1, h2|
    # h1 = h1.clone  # to preserve original hash (in ary)
    h1[:value] += h2[:value]
    h1

    # OR
    # h1.merge(h2) { |key, oldval, newval|
    #   key == :value ? oldval + newval : oldval
    # }
  }
}

# => [{:id=>0, :value=>["titi", "tata"], :allow=>true},
#     {:id=>1, :value=>["blabla"], :allow=>true},
#     {:id=>2, :value=>["ok", "ko"], :allow=>true}]

答案 1 :(得分:0)

这样做的一种方法是使用Hash#update(aka merge!)的形式,它使用块来确定合并的两个哈希中存在的键的值。

arr = [
  { id: 0, value: ["titi"],   allow: true },
  { id: 0, value: ["tata"],   allow: true }, 
  { id: 1, value: ["blabla"], allow: true }, 
  { id: 2, value: ["ok"],     allow: true }, 
  { id: 2, value: ["ko"],     allow: true }
]

arr.each_with_object({}) { |g,h|
  h.update(g[:id]=>g) { |_k,o,n| o.merge(value: o[:value]+n[:value]) } }.
    values.
    map { |g| g.merge(text: g[:value].join(', ')) }
  #=> [{:id=>0, :value=>["titi", "tata"], :allow=>true, :text=>"titi, tata"},
  #    {:id=>1, :value=>["blabla"], :allow=>true, :text=>"blabla"},
  #    {:id=>2, :value=>["ok", "ko"], :allow=>true, :text=>"ok, ko"}]

我 有关块变量_kon的说明,请参阅doc。 _k中的(可选)下划线表示块计算中未使用该块变量。

在最后使用values提取哈希值之前,我们计算了以下内容:

arr.each_with_object({}) { |g,h|
  h.update(g[:id]=>g) { |_k,o,n| o.merge(value: o[:value]+n[:value]) } }
    #=> {0=>{:id=>0, :value=>["titi", "tata"], :allow=>true},
    #    1=>{:id=>1, :value=>["blabla"], :allow=>true},
    #    2=>{:id=>2, :value=>["ok", "ko"], :allow=>true}}