更新,打印等,每个键具有多个值的散列中的各个值

时间:2014-08-01 18:29:26

标签: ruby hash

我正在努力建立一些逻辑来解决Coudal"谁的鱼?"难题。可能有更好的方法来存储和处理事物,但是现在我使用五个哈希值,其中有五个键,每个键都有五个值,随后是拼图。

 House1 = {"color"=>["red","grn","blu",...etc],
            "pet" =>["horse","bird","cat",...etc],
            ...etc }

有没有办法在数字上访问这些值?例如,我想只更新值" bird"成为别的东西。宠物是第二个关键,鸟是第二个关键。

我希望能够做到这样的事情(这里不是实际代码,对不起)

 Go find key 2, value 2, and replace value 2 with "X"
 Go find key 2, value 2, and compare value 2 with "Y"
 Go find key 2, value 2, and print value 2 on the screen

使用单个值完成此操作非常简单,但我无法在此处找到任何有关此内容的讨论。当然,我可以像这样设置哈希 -

 house1 = { "col1"=>"red","col2"=>"grn" ... "pet1"=>"horse", ... etc}

但这很容易让人难以理解和思考。

3 个答案:

答案 0 :(得分:0)

有两种想法:

house1 # => {"color"=>["red", "grn", "blu"], "pet"=>["horse", "bird", "cat"]}
house1_ary = house1.to_a
house1_ary[1] # => ["pet", ["horse", "bird", "cat"]]
house1_ary[1][1] # => ["horse", "bird", "cat"]
house1_ary[1][1][1] # => "bird"
house1_ary[1][1][1] = 'octochicken'
house1_ary # => [["color", ["red", "grn", "blu"]], ["pet", ["horse", "octochicken", "cat"]]]

转换回哈希很容易。对于Ruby 2.0 +:

house1_ary.to_h # => {"color"=>["red", "grn", "blu"], "pet"=>["horse", "octochicken", "cat"]}

否则:

Hash[house1_ary] # => {"color"=>["red", "grn", "blu"], "pet"=>["horse", "octochicken", "cat"]}

或者:

Hash[*house1_ary.flatten(1)] # => {"color"=>["red", "grn", "blu"], "pet"=>["horse", "octochicken", "cat"]}

可以使用一个整数作为密钥,这将允许你做你所说的,同时将所有内容保存在哈希中。它很容易创建:

house1 = {
  "color"=>["red","grn","blu"],
  "pet" =>["horse","bird","cat"],
}

house1_by_int = (0..(house1.size - 1)).to_a.zip(house1.values).to_h
# => {0=>["red", "grn", "blu"], 1=>["horse", "bird", "cat"]}

house1_by_int[1] # => ["horse", "bird", "cat"]
house1_by_int[1][1] # => "bird"
house1_by_int[1][1] = 'octochicken'
house1_by_int # => {0=>["red", "grn", "blu"], 1=>["horse", "octochicken", "cat"]}

无论哪种方式,您还将更新原始house1中的值,因为值将指向相同的数组:

house1 # => {"color"=>["red", "grn", "blu"], "pet"=>["horse", "octochicken", "cat"]}

  

没有理由我不能用数字作为键值.1表示房子,2表示宠物等。

嗯,是的,可能会有。我们使用哈希值,因为键/值对更容易被记住和理解,随着数据的增长,这有助于减少维护问题。

解决这个问题的另一种方法是创建一个小表来映射整数值和键的实际名称:

key_map = Hash[[*(0..(house1.size - 1))].zip(house1.keys)]
# => {0=>"color", 1=>"pet"}

house1[key_map[1]] # => ["horse", "bird", "cat"]
house1[key_map[1]][1] = 'octochicken'
house1 # => {"color"=>["red", "grn", "blu"], "pet"=>["horse", "octochicken", "cat"]}

这样做可以保留原始哈希,同时允许您灵活地处理哈希元素,并且它的外观和工作方式类似于使用数组索引。

答案 1 :(得分:0)

自Ruby v1.9起,哈希的元素保持其顺序,但通常应该将键值对视为无序。也就是说,基于散列中的偏移量来提取或更改键值对并不是一种好的编程习惯。

你可以这样做你想做的三件事:

让:

h = {"color"=>["red","grn","blu"],
     "pet"  =>["horse","bird","cat"],
     "grub" =>["pancakes", "waffles", "donuts"]}

查找键2,值2,并将值2替换为“X”

我想将其更改为:

h["pet"][1]替换为值"X"

def replace(h, key, offset, replacement)
  h[key][offset] = replacement
end

replace(h, "pet", 1, "X")
  #=> "X"
h
  #=> {"color"=>["red", "grn", "blu"],
  #    "pet"  =>["horse", "X", "cat"],
  #    "grub" =>["pancakes", "waffles", "donuts"]}

找到键2,值2,并将值2与“Y”进行比较

在屏幕上找到键2,值2和打印值

将这些更改为:

h["pet"][1]与值"Y"

进行比较

打印h["pet"][1]

def extract(h, key, offset)
  h[key][offset]
end

extract(h, "pet", 1) == "Y"
  #=> false
puts extract(h, "pet", 1)
  # bird

答案 2 :(得分:0)

您的示例的一个解决方案,忽略错误选择的数据类型:

House1 = {"color"=>["red","grn","blu"],
          "pet"  =>["horse","bird","cat"]}

# singleton method to update value at given index(es)    
def House1.update_at(key_ix, val_ix, val)
  entries[key_ix][1][val_ix] = val
  self
end

p House1.update_at 1, 1, 'xxx'
# {"color"=>["red", "grn", "blu"], "pet"=>["horse", "xxx", "cat"]}

顺便说一句。变量名称应以小写字符开头