C. Yee
C. Yee

Reputation: 197

Turning one array into two hashes

I want to split:

array = [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]

into two hashes like this:

hash1 = {"a" => "b", "d" => "e", "g" => "h"}
hash2 = {"a" => "c", "d" => "f", "g" => "i"}

Is there a way to do this?

Upvotes: 0

Views: 95

Answers (4)

Stefan Pochmann
Stefan Pochmann

Reputation: 28626

Just two more ways, though the first one destructs your array in the process.

Build hash2 first by popping so hash1 becomes trivial:

hash2 = array.map { |a| [a[0], a.pop] }.to_h
hash1 = array.to_h

First separate key and values columns, then zip them back together:

k, *v = array.transpose
hash1, hash2 = v.map { |v| k.zip(v).to_h }

(Thanks to Sagar Pandya for that, I had used k, *v = array.shift.zip(*array) before.)

Upvotes: 1

Stefan
Stefan

Reputation: 114218

A simple each loop would work:

array = [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]

hash1 = {}
hash2 = {}

array.each do |k, v1, v2|
  hash1[k] = v1
  hash2[k] = v2
end

hash1 #=> {"a"=>"b", "d"=>"e", "g"=>"h"}
hash2 #=> {"a"=>"c", "d"=>"f", "g"=>"i"}

Upvotes: 3

Cary Swoveland
Cary Swoveland

Reputation: 110725

array = [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]

hash1 = array.map { |f,m,_| [f,m] }.to_h
  #=> {"a"=>"b", "d"=>"e", "g"=>"h"}
hash2 = array.map { |f,_,l| [f,l] }.to_h
  #=> {"a"=>"c", "d"=>"f", "g"=>"i"}

or

def doit(arr, i1, i2)
  arr.map { |a| [a[i1], a[i2]] }.to_h
end

hash1 = doit(array, 0, 1)
  #=> {"a"=>"b", "d"=>"e", "g"=>"h"}
hash2 = doit(array, 0, 2)
  #=> {"a"=>"c", "d"=>"f", "g"=>"i"}

Upvotes: 5

Sergio Belevskij
Sergio Belevskij

Reputation: 2957

array = [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]
hashes = {}
array.each do |subarray|
  subarray[1..-1].each_with_index do |item, index|
    hashes[index] ||= {}
    hashes[index][subarray.first] = item
  end
end

puts hashes.values

Upvotes: 0

Related Questions