Converting a Ruby array of tuples to a hash sets an array of keys?

I have a simple array

array = ["apple", "orange", "lemon"] 

array2 = [["apple", "good taste", "red"], ["orange", "bad taste", "orange"], ["lemon" , "no taste", "yellow"]]

how can i convert to this hash whenever an element in an array matches the first element of each element in an array2?

hash = {"apple" => ["apple" ,"good taste", "red"],
        "orange" => ["orange", "bad taste", "orange"], 
        "lemon" => ["lemon" , "no taste", "yellow"] }

I am new to the ruby ​​and spend a lot on this manipulation, but no luck, no help?

+8
source share
4 answers

If the display order between the key and the pairs should be based on the first element in array2, you do not need to array:

array2 = [
  ["apple", "good taste", "red"],
  ["lemon" , "no taste", "yellow"],
  ["orange", "bad taste", "orange"]
]

map = Hash[ array2.map{ |a| [a.first,a] } ]
p map
#=> {
#=>   "apple"=>["apple", "good taste", "red"],
#=>   "lemon"=>["lemon", "no taste", "yellow"],
#=>   "orange"=>["orange", "bad taste", "orange"]
#=> }

If you want to use a arraysubset of elements to select, you can do this:

# Use the map created above to find values efficiently
array = %w[orange lemon]
hash  = Hash[ array.map{ |val| [val,map[val]] if map.key?(val) }.compact ]
p hash
#=> {
#=>   "orange"=>["orange", "bad taste", "orange"],
#=>   "lemon"=>["lemon", "no taste", "yellow"]
#=> }

The code if map.key?(val)also compactensures that there is no problem if it arrayrequests keys that are absent in array2, and does so in O(n)time.

+13

.

hash = {}

array.each do |element|
  i = array2.index{ |x| x[0] == element }
  hash[element] = array2[i] unless i.nil?
end
+2

fruit_values = [
  ['apple', 10],
  ['orange', 20],
  ['lemon', 5]
]

fruit_values.to_h
# => {"apple"=>10, "orange"=>20, "lemon"=>5} 

, .

Although this is slightly different from the question, it was here that I got into my Google search. This also corresponded slightly to the original question due to the fact that the array of keys was already in the tuples. This also does not give a clue to the value that the original question wanted, but I honestly will not duplicate this data.

0
source

ohh..I am tempted to override rassoc

Please note the following: irb

class Array
  def rassoc obj, place=1
    if place
      place = place.to_i rescue -1
      return if place < 0
    end

    self.each do |item|
      next unless item.respond_to? :include? 

      if place
        return item if item[place]==obj
      else
        return item if item.include? obj
      end
    end

    nil
  end
end

array = ["apple", "orange", "lemon"] 
array2 = [["apple", "good taste", "red"], ["orange", "bad taste", "orange"], ["lemon" , "no taste", "yellow"]]

Hash[ array.map{ |fruit| [fruit, array2.rassoc(fruit, nil)]}]
# this is what you want

# order changed
array2 = [["good taste", "red", "apple"], ["no taste", "lemon", "yellow"], ["orange", "bad taste", "orange"]]

Hash[ array.map{ |fruit| [fruit, array2.rassoc(fruit, nil)]}]
# same what you want after order is changed
-1
source

All Articles