从ruby中具有相同值的数组返回键

时间:2015-10-19 05:30:28

标签: arrays ruby duplicates

如何找出具有相同value_entries的数组元素。代码是红宝石,看起来更好的方法。

输入

"block_device": {
  "sda": {
    "size": "83886080",
    "removable": "0",
    "model": "VBOX HARDDISK",
    "rev": "1.0",
    "state": "running",
    "timeout": "30",
    "vendor": "ATA",
    "rotational": "1"
  },
  "sdb": {
    "size": "16384",
    "removable": "0",
    "model": "VBOX HARDDISK",
    "rev": "1.0",
    "state": "running",
    "timeout": "30",
    "vendor": "ATA",
    "rotational": "1"
  },
  "sdc": {
    "size": "16384",
    "removable": "0",
    "model": "VBOX HARDDISK",
    "rev": "1.0",
    "state": "running",
    "timeout": "30",
    "vendor": "ATA",
    "rotational": "1"
  }
}

示例代码阻止:

devicesForRaid = []
deviceHolder = []
node['block_device'].each do |deviceName,deviceProperty|
   deviceHolder.push(deviceName,deviceProperty['size'])       #['sda'=>'83886080','sdb'=>'16384','sdc'=>'16384']
end

deviceHolder.each do | deviceName,deviceSize|

    # how to get deviceName who all having same size

    if(deviceSize_match_found){
        devicesForRaid.push(deviceName)
    }
end

预期输出:

devicesForRaid = ['sdb','sdc']

试用方式:

使用堆栈, 将第一个元素推入堆栈,并与数组元素的其余部分进行比较。

如果找到匹配,则将该元素推送到堆栈。

示例代码块完成或更好的代码高度赞赏。

4 个答案:

答案 0 :(得分:2)

你可以这样做:

input_hash[:block_device].each_with_object({}) { |(k,g),h|
  h.update(g[:size]=>[k]) { |_,o,n| o+n } }
  #=> {"83886080"=>[:sda], "16384"=>[:sdb, :sdc]} 

这使用了使用块的Hash#update(aka merge!)形式:

{ |_,o,n| o+n }

确定合并的两个哈希中存在的键的值。

答案 1 :(得分:1)

res = Hash.new { |h, k| h[k] = [] }
node['block_device'].each{|k, v| res[v[:size]]<<k}

给出:

=> {"83886080"=>[:sda], "16384"=>[:sdb, :sdc]}

我想你想通过res查看长度为2或更多的值

res.to_a.select{|k, v| v.size > 1}

答案 2 :(得分:0)

你可以这样做(假设block_device是输入数据哈希中的一个键):

hash = input_data[:block_device]
new_hash = Hash.new{ |h, k| h[k] = [] }
hash.each do |k, v|
  new_hash[v[:size]] << k
end
p new_hash
# => {"83886080"=>[:sda], "16384"=>[:sdb, :sdc]}

通过此new_hash,您可以轻松提取所需数据。

e.g。如果要提取大小超过1的元素,可以执行以下操作:

p new_hash.select { |k,v| v.length > 1 }.values.flatten
# => [:sdb, :sdc]

答案 3 :(得分:0)

如何使用node[:block_device] .group_by {|device, attributes| attributes[:size] } .map {|size, devices| devices.size > 1 ? devices.map(&:first) : nil } .compact .flatten => [:sdb, :sdc]

SelectList

我认为这种方式很容易理解你在做什么。