Dans Ruby 2.4, comment puis-je trouver le premier index d'un élément d'un tableau dans un autre tableau? En d’autres termes, si un élément d’un tableau apparaît dans l’autre, je souhaite obtenir le premier index. Je pensais que find_index pourrait le faire, mais
2.4.0 :004 > a = ["a", "b", "c"]
=> ["a", "b", "c"]
2.4.0 :005 > a.find_index("a")
=> 0
2.4.0 :006 > a.find_index(["b", "c"])
=> nil
Dans l'exemple ci-dessus, je m'attendrais à voir la sortie "1" car l'élément "b" apparaît à l'index 1 du tableau "a".
find_index
prend un seul élément. Vous pouvez trouver le minimum en faisant quelque chose comme
a = ["a", "b", "c"]
to_find = ["b", "c"]
to_find.map {|i| a.find_index(i) } .compact.min # => 1
Vous pouvez utiliser Array#index
avec un bloc.
a = ['a', 'b', 'c']
a.index { |x| ['b', 'c'].include?(x) }
#=> 1
Citation de la documentation:
Si un bloc est donné à la place d'un argument, renvoie l'index du premier objet pour lequel le bloc renvoie la valeur true. Renvoie la valeur nil si aucune correspondance n'est trouvée.
Comme Cary l'a fait remarquer dans son commentaire, l'algorithme le plus performant n'est pas de comparer tous les éléments de a
à tous les éléments de ['b', 'c']
(cela conduirait à O(n*m)
). En fonction de la taille des deux tableaux, il peut être judicieux de commencer par créer une structure de données plus efficace. L'utilisation d'une Set
au lieu d'un tableau a un coût pour créer la set
au début, mais rend la comparaison beaucoup plus rapide dans le bloc (O(n+m)
dans son ensemble):
require 'set'
a = ['a', 'b', 'c']
set = Set.new(['b', 'c'])
a.index { |x| set.include?(x) }
#=> 1
Vous pouvez utiliser find_index
et transmettre la valeur requise du tableau:
a = ["a", "b", "c"]
p a.find_index('a')
p a.find_index('b')
p a.find_index('c')
# => 0
# => 1
# => 2
Vous pouvez utiliser map
pour obtenir tous les éléments de votre tableau a
, puis pour obtenir l'index correspondant à chaque élément:
p a.map{|e| a.find_index(e)}
# => [0, 1, 2]
Une autre façon de gérer cela pourrait être d'utiliser le Enumerable#each_with_index
:
a.each_with_index{|e,i| puts "Element: #{e}, Index: #{i}"}
# => Element: a, Index: 0
# => Element: b, Index: 1
# => Element: c, Index: 2
Si vous souhaitez vérifier les index de chaque élément dans ["b", "c"]
à l'aide du tableau ["a", "b", "c"]
, vous pouvez mapper le premier, obtenir les valeurs du tableau, puis utiliser le a,b,c
pour vérifier ces index:
p ["b", "c"].map{|e| ["a", "b", "c"].find_index(e) }
# => [1, 2]
Vous pouvez également voir Array#index
et Enumerable#find_index
.
Vous pouvez trouver l'index de tous les éléments du tableau b
dans le tableau a
et trouver l'index min pour rechercher l'index auquel un élément du tableau b
est apparu en premier dans array a
.
Quelque chose comme ci-dessous:
a = ["a", "b", "c"]
b = ["b", "c"]
b.map { |x| a.find_index(x) }.min
#=> 1