在给定一组键的情况下,将Ruby元组的元组转换为哈希?

时间:2012-06-08 04:13:40

标签: ruby arrays

我有一个简单的数组

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

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

当数组中的元素与array2中每个元素的第一个元素匹配时,我怎么能转换为这个哈希?

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

我对红宝石很陌生,花了很多钱去做这个操作,但没有运气,有什么帮助吗?

4 个答案:

答案 0 :(得分:12)

如果密钥和对之间的映射顺序应该基于array2中的第一个元素,那么您根本不需要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"]
#=> }

如果您想使用array选择元素的子集,那么您可以这样做:

# 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"]
#=> }

代码if map.key?(val)compact可确保array请求array2中不存在的密钥时出现问题,并且O(n)时间。

答案 1 :(得分:2)

这可以获得理想的结果。

hash = {}

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

答案 2 :(得分:0)

将元组配对为哈希示例

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

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

我决定将这个答案留给所有希望将成对的元组转换为哈希的人。

尽管与问题稍有不同,但这是我进入Google搜索的地方。由于元组中已经存在键数组,因此它也与原始问题有点匹配。这也没有将密钥放入原始问题想要的值中,但是老实说我不会重复该数据。

答案 3 :(得分:-1)

哦......我试图覆盖rassoc

在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