如何检查是否有任何子阵列不包含其他子阵列中的项目?红宝石

时间:2017-07-06 06:10:47

标签: arrays ruby sub-array

我有一个数组

animals = [
  [{"name" => "Alex", "spices" => "dog", "vname" => "colour", "value" => "black"}, 
   {"name" => "Alf", "spices" => "dog", "vname" => "colour", "value" => "white"}, 
   {"name" => "Sonia", "spices" => "dog", "vname" => "colour", "value" => "white"}],

  [{"name" => "Alex", "spices" => "dog", "vname" => "health", "value" => "80"}, 
   {"name" => "Alf", "spices" => "dog", "vname" => "health", "value" => "98"}],

  [{"name" => "Alex", "spices" => "dog", "vname" => "age", "value" => "12"}]
]

每只动物(亚历克斯,阿尔夫和索尼娅)都是根据颜色,健康状况和年龄(vname值)来描述的,但是Alf在第三个子阵列中没有年龄的哈希值,而Sonia没有健康的哈希值(第二个子阵列)和年龄(第三个子阵列)。我想检查是否有任何子阵列没有某些狗的“vname”对,如果不添加像这样的哈希

{"name" => "Alf", "spices" => "dog", "vname" => "age", "value" => "unknown"}

获取数组

animals = [
 [{"name" => "Alex", "spices" => "dog", "vname" => "colour", "value" => "black"},
  {"name" => "Alf", "spices" => "dog", "vname" => "colour", "value" => "white"}, 
  {"name" => "Sonia", "spices" => "dog", "vname" => "colour", "value" => "white"}],

 [{"name" => "Alex", "spices" => "dog", "vname" => "health", "value" => "80"}, 
  {"name" => "Alf", "spices" => "dog", "vname" => "health", "value" => "98"}, 
  {"name" => "Sonia", "spices" => "dog", "vname" => "health", "value" => "unknown"}],

 [{"name" => "Alex", "spices" => "dog", "vname" => "age", "value" => "12"}, 
  {"name" => "Alf", "spices" => "dog", "vname" => "age", "value" => "unknown"}, 
  {"name" => "Sonia", "spices" => "dog", "vname" => "age", "value" => "unknown"}]
]

你可以帮帮我吗?

2 个答案:

答案 0 :(得分:2)

嗯。在数组中设置名称。循环遍历animals数组,并为每个数组内部检查是否有所有动物名称的哈希值。为缺少的那些添加默认哈希。

    animal_names = ["Alex", "Alf", "Sonia"]

    animals.each do |animals_by_vname|
      vname         = animals_by_vname.first["vname"]
      names_present = animals_by_vname.map {|i| i["name"]}
      names_missing = animal_names - names_present

      names_missing.each do |name|
        animals_by_vname << {
          "name"   => name,
          "spices" => "dog",
          "vname"  => vname,
          "value"  => "unknown"
        }
      end
    end

    puts animals # should be you wanted it.

这解决了你的问题。

但是,老实说,我认为数据结构需要优化。也许有一个带有动物名称作为键的数组哈希。像:

    {
      "Alex": { health: "good" }
      "Alf": { age: 10, health: "good" }
    }

答案 1 :(得分:1)

您的数据格式很难处理。

您可以定义Animal类,保留Animal.all哈希并在此结构中写入数据:

data = [
  [{ 'name' => 'Alex', 'spices' => 'dog', 'vname' => 'colour', 'value' => 'black' },
   { 'name' => 'Alf', 'spices' => 'dog', 'vname' => 'colour', 'value' => 'white' },
   { 'name' => 'Sonia', 'spices' => 'dog', 'vname' => 'colour', 'value' => 'white' }],

  [{ 'name' => 'Alex', 'spices' => 'dog', 'vname' => 'health', 'value' => '80' },
   { 'name' => 'Alf', 'spices' => 'dog', 'vname' => 'health', 'value' => '98' }],

  [{ 'name' => 'Alex', 'spices' => 'dog', 'vname' => 'age', 'value' => '12' }]
]

class Animal
  attr_accessor :name, :species, :health, :age, :colour
  @all = {}

  class << self
    attr_reader :all

    def find_or_create_by_name(params)
      all[params['name']] ||= Animal.new(params)
    end
  end

  def initialize(params)
    @name = params['name']
    @species = params['spices']
  end

  def to_h
    {
      name: name,
      species: species,
      age: age || 'unknown',
      colour: colour || 'unknown',
      health: health || 'unknown'
    }
  end

  def to_s
    to_h.to_s
  end

  alias inspect to_s
end

data.each do |info|
  info.each do |params|
    animal = Animal.find_or_create_by_name(params)
    animal.instance_variable_set("@#{params['vname']}", params['value'])
  end
end

require 'pp'
pp Animal.all
# {"Alex"=>
#   {:name=>"Alex", :species=>"dog", :age=>"12", :colour=>"black", :health=>"80"},
#  "Alf"=>
#   {:name=>"Alf", :species=>"dog", :age=>"unknown", :colour=>"white", :health=>"98"},
#  "Sonia"=>
#   {:name=>"Sonia", :species=>"dog", :age=>"unknown", :colour=>"white", :health=>"unknown"}}