211 votes

Ruby / Rails: Comment déterminer si un tableau contient tous les éléments d'un autre tableau?

Donné:

 a1 = [5, 1, 6, 14, 2, 8]
 

Je voudrais déterminer s'il contient tous les éléments de:

 a2 = [2, 6, 15]
 

Dans ce cas, le résultat est false .

Existe-t-il une méthode Ruby / Rails intégrée pour identifier une telle inclusion de tableau?

Une façon d'implémenter ceci est:

 a2.index{ |x| !a1.include?(x) }.nil?
 

Y a-t-il une meilleure façon, plus lisible?

371voto

Tempus Points 22972
a = [5, 1, 6, 14, 2, 8]
b = [2, 6, 15]

a - b
=> [5, 1, 14, 8]

b - a
=> [15]

(b - a).empty?
=> false

94voto

Pablo Fernandez Points 32003

C'est peut-être plus facile à lire:

 a2.all? { |e| a1.include?(e) }
 

Vous pouvez également utiliser l'intersection de tableau:

 (a1 & a2).size == a1.size
 

Notez que size est utilisé ici juste pour la vitesse, vous pouvez aussi faire (plus lentement):

 (a1 & a2) == a1
 

Mais je suppose que le premier est plus lisible. Ces 3 sont en rubis ordinaire (pas de rails).

63voto

Holger Just Points 17345

Ceci peut être réalisé en faisant

(a2 & a1) == a2

Cela crée l'intersection de deux tableaux, le retour de tous les éléments d' a2 qui sont également en a1. Si le résultat est le même qu' a2, vous pouvez être sûr que vous avez tous les éléments inclus dans a1.

Edit: Cette approche ne fonctionne que si tous les éléments en a2 sont différents les uns des autres, en premier lieu. Si il y a des doubles, cette approche ne tient pas. L'un de Tempos fonctionne encore, donc je recommande de tout cœur de son approche (c'est aussi probablement plus rapide).

12voto

Confusion Points 6056

S'il n'y a pas d'éléments en double ou si vous ne les aimez pas, vous pouvez utiliser la classe Set :

 a1 = Set.new [5, 1, 6, 14, 2, 8]
a2 = Set.new [2, 6, 15]
a1.subset?(a2)
=> false
 

En coulisse, cela utilise

 all? { |o| set.include?(o) }
 

0voto

ayckoster Points 2836

En fonction de la taille de vos tableaux, vous pourriez envisager un algorithme efficace O (n log n)

 def equal_a(a1, a2)
  a1sorted = a1.sort
  a2sorted = a2.sort
  return false if a1.length != a2.length
  0.upto(a1.length - 1) do 
    |i| return false if a1sorted[i] != a2sorted[i]
  end
end
 

Trier les coûts O (n log n) et vérifier chaque paire coûte O (n) donc cet algorithme est O (n log n). Les autres algorithmes ne peuvent pas être plus rapides (asymptotiquement) en utilisant des tableaux non triés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X