Reputation: 1936
I want to convert this array
[['a', 'b'],['c', 'd'],['e', 'f']]
to this hash
{
"a" : "c",
"b" : "d"
},
{
"a" : "e",
"b" : "f"
}
How to do it?
I tried to use group_by
and normal iterators but no luck so far. Any ideas?
Upvotes: 2
Views: 2329
Reputation: 13901
I would write:
key = a.shift
p a.map{|x| key.zip(x).to_h } => [{"a"=>"c", "b"=>"d"}, {"a"=>"e", "b"=>"f"}]
Upvotes: 1
Reputation: 110675
I would use Array#product:
arr = [[:a, :b], [:c, :d], [:e, :f]]
arr.first.product(arr[1..-1]).map(&:to_h)
#=> [{:a=>:c, :b=>:d}, {:a=>:e, :b=>:f}]
If arr
can be modified, we can write:
arr.shift.product(arr).map(&:to_h)
Upvotes: 2
Reputation: 121000
▶ arr = [[:a, :b],[:c, :d],[:e, :f],[:g, :h]]
▶ key, values = arr.first, arr[1..-1]
▶ values.map { |v| key.zip v }.map &:to_h
#⇒ [
# [0] {
# :a => :c,
# :b => :d
# },
# [1] {
# :a => :e,
# :b => :f
# },
# [2] {
# :a => :g,
# :b => :h
# }
# ]
Please note that unlike other solutions presented here at the moment this one will map first element as keys to a tail of arbitrary length.
UPD For legacy rubies, not having Array#to_h
:
values.map { |v| key.zip v }.map { |e| Hash[e] }
Upvotes: 7
Reputation: 8821
a= [['a', 'b'],['c', 'd'],['e', 'f']]
a[1..-1].inject([]) { |sum, s| sum << {a[0][0] => s[0], a[0][1] => s[1]} }
=> [{"a"=>"c", "b"=>"d"}, {"a"=>"e", "b"=>"f"}]
improved:
a= [['a', 'b', 'c'],['d', 'e', 'f'],['g', 'h', 'k']]
a[1..-1].inject([]) do |sum, s|
hash = {}
a[0].each_with_index { |it, i| hash.merge!({it => s[i]}) }
sum << hash
end
=> [{"a"=>"d", "b"=>"e", "c"=>"f"}, {"a"=>"g", "b"=>"h", "c"=>"k"}]
This way is more flexible.
Upvotes: 1
Reputation: 1572
x = [["a", "b"],["c", "d"],["e", "f"]]
x[1..-1].map { |vs| {x[0][0] => vs[0], x[0][1] => vs[1]} }
Something like this.
Upvotes: 1