2017-07-06 2 views
2

J'ai un tableaucomment vérifier si aucun sous-tableau ne contient un élément d'un autre sous-réseau? Ruby

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

Tous les animaux (Alex, Alf et Sonia) est décrit par la couleur, la santé et l'âge (valeurs vNom), mais Alf n'a pas son hachage avec l'âge à la troisième sous-tableau et Sonia n'a pas ses hachages avec la santé (deuxième sous-tableau) et l'âge (troisième sous-tableau). Je veux vérifier si un sous-tableau n'a pas « vname » paire pour un chien et si ne pas ajouter de hachage comme celui-ci

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

pour obtenir un tableau

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

Pouvez-vous me aider ce?

+0

Ce n'est pas du tout clair. Pouvez-vous au moins essayer de faire du code? L'utilisation de touches de symboles ('name:" Alex "') réduirait aussi beaucoup la verbosité ici. – tadman

+1

Voulez-vous dire "espèces" au lieu de "épices"? – tadman

+1

Je pense que la structure de données peut être optimisée pour résoudre ce problème. D'où viennent ces données? Est-ce une option d'utiliser une autre structure de données ou de traduire en objet de valeur une option? – spickermann

Répondre

2

Umm. Définissez les noms dans un tableau. Parcourez votre tableau animals et pour chacun des tableaux à l'intérieur, vérifiez si has hash pour tous les noms d'animaux. Ajoutez le hachage par défaut pour ceux qui manquent.

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. 

Cela résout votre problème.

Cependant, je crois honnêtement, la structure de données doit être optimisée. Peut-être avoir un hachage de tableaux avec des noms d'animaux comme clés. Comme:

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

True. Mise à jour de la structure suggérée – aBadAssCowboy

1

Votre format de données est très difficile à utiliser.

Vous pouvez définir une classe Animal, garder un hachage Animal.all et écrire vos données dans cette structure:

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"}}