2

How to group array of hashes into one "groupname" and "id" hash and push elements occurring after "words" keyword into array of hashes? I can't find similar issue.

My flat input:

[{
    "id" => "1",
    "groupname" => "Unit 1",
    "words" => nil,
    "unit" => "1",
    "name" => "asdfwe"
}, {
    "id" => "1",
    "groupname" => "Unit 1",
    "words" => nil,
    "unit" => "1",
    "name" => "testasdf"
}, {
    "id" => "2",
    "groupname" => "Unit 2",
    "words" => nil,
    "unit" => "2",
    "name" => "test2wewe"
}, {
    "id" => "2",
    "groupname" => "Unit 2",
    "words" => nil,
    "unit" => "2",
    "name" => "test2sadf"
}]

Desired output:

[{
    "id" => "1",
    "groupname" => "Unit 1",
    "words" => [{
        "unit" => "1",
        "name" => "asdfwe"
    }, {
        "unit" => "1",
        "name" => "testasdf"
    }]
}, {
    "id" => "2",
    "groupname" => "Unit 2",
    "words" => [{
        "unit" => "2",
        "name" => "test2wewe"
    }, {
        "unit" => "2",
        "name" => "test2sadf"
    }]
}]

Current not working as expected steps:

out = []
arrhsh.each_with_index do |hsh,index|
  hsh.each do |(k,v)|
    if k === "words"
      newhsh = {}
      newhsh["id"] = hsh["id"]
      newhsh["groupname"] = hsh["groupname"]
      newhsh["words"] = []
      wordshsh = {
        "unit" => hsh["unit"],
        "name" => hsh["name"]
      }
      newhsh["words"] << wordshsh
      out << newhshq
    end
  end
end
out.group_by {|h| h["id"]}
3
  • 3
    Have you tried something? Commented Apr 14, 2015 at 10:59
  • only group_by one key. Commented Apr 14, 2015 at 11:04
  • 2
    please include your attempts. Commented Apr 14, 2015 at 11:05

1 Answer 1

1

What about this?

b = a.group_by { |i| i['id'] }.map do |id, group|
  {
    id: id,
    groupname: group.first['groupname'],
    words: group.map { |g| g.slice('unit', 'name') }
  }
end
Sign up to request clarification or add additional context in comments.

1 Comment

g.slice('unit', 'name') produces an error because there is no slice method in the Hash class. words: group.map { |g| g.select { |k,_| k.match(/\bname\b|\bunit\b/) } } fixes this problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.