将单个数组合并到Rails的嵌套数组中

时间:2019-10-10 09:30:30

标签: ruby-on-rails ruby

我有一个类似这样的对象列表:

      a = [
          {
              id: 0,
              name: "ABC",
              work: "ABC2"
          },
          {
              id: 0,
              name: "XYZ",
              work: "XYZ2"
          },
          {
              id: 1,
              name: "ACD",
              work: "ACD2"
          }
      ]

我想将其转换为这样的内容:

      b = [
            {
              id: 0,
              fields: [
                  {
                    name: "ABC",
                    work: "ABC2"
                  },
                  {
                    name: "XYZ",
                    work: "XYZ2"
                  }
                ]
            },

            {
                id: 1,
                fields: [
                    {
                        name: "ACD",
                        work: "ACD2"
                    }
                ]
            }
      ]

想法是将对象按ID分组在一个数组中。

我尝试的方法是:

      b = []

      rest_object = []

      a.each_with_index do |aa, idx|

        aa.delete(:id)

        rest_object << aa

        if idx == 0
          next
        end

        puts a[idx][:id], a[idx-1][:id]

        if a[idx][:id] != a[idx-1][:id]
          b << {id: a[idx-1][:id], names: rest_object}
          rest_object = []
        end

      end

但是我得到的输出是空的。

此外,如果有可能以更简洁的方式实现相同目标。 那会有所帮助。

4 个答案:

答案 0 :(得分:1)

类似的事情可以完成。这将从每个哈希中删除:id键值对,并使用该值对group哈希的其余部分。然后map生成的哈希值创建一个数组,并将数据转换为{id: ..., fields: ...}格式。

a = [{id: 0, name: "ABC", work: "ABC2"}, {id: 0, name: "XYZ", work: "XYZ2"}, {id: 1, name: "ACD", work: "ACD2"}]

b = a.group_by { |hash| hash.delete(:id) }
     .map { |id, fields| {id: id, fields: fields} }
#=> [{:id=>0, :fields=>[{:name=>"ABC", :work=>"ABC2"}, {:name=>"XYZ", :work=>"XYZ2"}]}, {:id=>1, :fields=>[{:name=>"ACD", :work=>"ACD2"}]}]

注意::这会使a数组中的哈希值发生变化。如果您不希望将此更改从a.group_by更改为a.map(&:dup).group_by。在进行任何突变之前,哪个先复制所有哈希。

答案 1 :(得分:0)

尝试关注,

out

答案 2 :(得分:0)

  a = [
      {
          id: 0,
          name: "ABC"
      },
      {
          id: 0,
          name: "XYZ"
      },
      {
          id: 1,
          name: "ACD"
      }
  ]

ary = []
a.each do|val|
 ary[val[:id]] = {id: val[:id]} unless ary[val[:id]] 
 ary[val[:id]][:names] = [] unless ary[val[:id]][:names]
 ary[val[:id]][:names].push({name: val[:name]})
end

答案 3 :(得分:0)

如果我理解的话,给出一个更通用的数组:

a = [ { id: 0, name: "ABC", etc: "01" },
      { id: 0, name: "XYZ", etc: "02" },
      { id: 1, name: "ACD", etc: "11" } ]

我想到的第一个想法是做这样的事情:

require 'active_support/inflector' # for using pluralize

res = a.group_by{ |h| h[:id] }.values.map do |ary|
        h = Hash.new{ |h,k| h[k] = [] }
        ary.each { |hh| hh.each { |k,v| h[k] << v } }
        h[:id] = h[:id].first
        h.transform_keys do |k|
          unless k == :id
            k.to_s.pluralize.to_sym
          else
            k
          end
        end
      end

res #=> [{:id=>0, :names=>["ABC", "XYZ"], :etcs=>["01", "02"]}, {:id=>1, :names=>["ACD"], :etcs=>["11"]}]

这不完全是您需要的格式,但是要获取该格式,只需更改此行

ary.each { |hh| hh.each { |k,v| h[k] << v } }

ary.each { |hh| hh.each { |k,v| h[k] << { k => v } } }
相关问题