web-dev-qa-db-fra.com

Comment puis-je supprimer un élément d'un tableau par valeur

J'ai un tableau d'éléments en Ruby

[2,4,6,3,8]

Je dois supprimer des éléments avec la valeur 3 par exemple

Comment je fais ça?

294
Tamik Soziev

Je pense l'avoir compris:

a = [2,4,6,3,8]
a.delete(3)
416
Tamik Soziev

Emprunter auprès de Travis dans les commentaires, voici une meilleure réponse:

Personnellement, j'aime bien [1, 2, 7, 4, 5] - [7], ce qui donne => [1, 2, 4, 5] de irb

J'ai modifié sa réponse en voyant que 3 était le troisième élément de son exemple. Cela pourrait semer la confusion chez ceux qui ne réalisent pas que 3 est en position 2 dans le tableau. 

190
Abram

Une autre option:

a = [2,4,6,3,8]

a -= [3]

qui se traduit par

=> [2, 4, 6, 8] 
60
Steve

Je ne suis pas sûr que quelqu'un l'ait indiqué, mais Array.delete () et - = value vont supprimer toutes les instances de la valeur qui lui sont transmises dans le tableau. Afin de supprimer la première instance de l'élément particulier, vous pouvez faire quelque chose comme:

arr = [1,3,2,44,5]
arr.delete_at(arr.index(44))

#=> [1,3,2,5]

Il pourrait y avoir un moyen plus simple. Je ne dis pas que c'est une pratique exemplaire, mais c'est quelque chose qui devrait être reconnu.

33
Scott

J'aime la manière -=[4] mentionnée dans d'autres réponses pour supprimer les éléments dont la valeur est 4.

Mais il y a cette voie:

irb(main):419:0> [2,4,6,3,8,6].delete_if{|i|i==6}
=> [2, 4, 3, 8]
irb(main):420:0>

mentionné quelque part dans " Basic Array Operations ", après avoir mentionné la fonction map.

24
barlop

En supposant que vous vouliez supprimer 3 par la valeur à plusieurs endroits dans un tableau, Je pense que la méthode Ruby pour effectuer cette tâche serait d'utiliser la méthode delete_if:

[2,4,6,3,8,3].delete_if {|x| x == 3 } 

Vous pouvez également utiliser delete_if pour supprimer des éléments dans le scénario "tableau de tableaux".

J'espère que cela résoudra votre requête

20
Sayan

Vous pouvez simplement lancer:

[2,4,6,3,8].delete(3)
18
rilutham

Un .delete_at(3)3 étant ici la position.

18
Sawo Cliff

Voici quelques repères:

require 'fruity'


class Array          
  def rodrigo_except(*values)
    self - values
  end    

  def niels_except value
    value = value.kind_of?(Array) ? value : [value]
    self - value
  end
end

ARY = [2,4,6,3,8]

compare do
  soziev  { a = ARY.dup; a.delete(3);               a }
  steve   { a = ARY.dup; a -= [3];                  a }
  barlop  { a = ARY.dup; a.delete_if{ |i| i == 3 }; a }
  rodrigo { a = ARY.dup; a.rodrigo_except(3);         }
  niels   { a = ARY.dup; a.niels_except(3);           }
end

# >> Running each test 4096 times. Test will take about 2 seconds.
# >> soziev is similar to barlop
# >> barlop is faster than steve by 2x ± 1.0
# >> steve is faster than rodrigo by 4x ± 1.0
# >> rodrigo is similar to niels

Et encore avec un plus grand tableau contenant beaucoup de doublons:

class Array          
  def rodrigo_except(*values)
    self - values
  end    

  def niels_except value
    value = value.kind_of?(Array) ? value : [value]
    self - value
  end
end

ARY = [2,4,6,3,8] * 1000

compare do
  soziev  { a = ARY.dup; a.delete(3);               a }
  steve   { a = ARY.dup; a -= [3];                  a }
  barlop  { a = ARY.dup; a.delete_if{ |i| i == 3 }; a }
  rodrigo { a = ARY.dup; a.rodrigo_except(3);         }
  niels   { a = ARY.dup; a.niels_except(3);           }
end

# >> Running each test 16 times. Test will take about 1 second.
# >> steve is faster than soziev by 30.000000000000004% ± 10.0%
# >> soziev is faster than barlop by 50.0% ± 10.0%
# >> barlop is faster than rodrigo by 3x ± 0.1
# >> rodrigo is similar to niels

Et encore plus grand avec plus de doublons:

class Array          
  def rodrigo_except(*values)
    self - values
  end    

  def niels_except value
    value = value.kind_of?(Array) ? value : [value]
    self - value
  end
end

ARY = [2,4,6,3,8] * 100_000

compare do
  soziev  { a = ARY.dup; a.delete(3);               a }
  steve   { a = ARY.dup; a -= [3];                  a }
  barlop  { a = ARY.dup; a.delete_if{ |i| i == 3 }; a }
  rodrigo { a = ARY.dup; a.rodrigo_except(3);         }
  niels   { a = ARY.dup; a.niels_except(3);           }
end

# >> Running each test once. Test will take about 6 seconds.
# >> steve is similar to soziev
# >> soziev is faster than barlop by 2x ± 0.1
# >> barlop is faster than niels by 3x ± 1.0
# >> niels is similar to rodrigo
12
the Tin Man

J'ai amélioré la solution de Niels

class Array          
  def except(*values)
    self - values
  end    
end

Maintenant vous pouvez utiliser

[1, 2, 3, 4].except(3, 4) # return [1, 2]
[1, 2, 3, 4].except(4)    # return [1, 2, 3]
6
Rodrigo Mendonça

Vous pouvez aussi le patcher. Je n'ai jamais compris pourquoi Ruby utilise une méthode except pour Hash mais pas pour Array:

class Array
  def except value
    value = value.kind_of(Array) ? value : [value]
    self - value
  end
end

Maintenant vous pouvez faire:

[1,3,7,"436",354,nil].except(354) #=> [1,3,7,"436",nil]

Ou:

[1,3,7,"436",354,nil].except([354, 1]) #=> [3,7,"436",nil]
3
Niels Kristian

Ainsi, lorsque vous avez plusieurs occurrences de 3 et que vous souhaitez uniquement supprimer la première occurrence de 3, vous pouvez simplement procéder de la manière suivante.

arr = [2, 4, 6, 3, 8, 10, 3, 12]

arr.delete_at arr.index 3

#This will modify arr as [2, 4, 6, 8, 10, 3, 12] where first occurrence of 3 is deleted. Returns the element deleted. In this case => 3.
2
ashan priyadarshana

Si vous souhaitez également rendre cette opération de suppression chaînable, afin de pouvoir supprimer un élément et continuer à enchaîner les opérations sur le tableau résultant, utilisez tap

[2, 4, 6, 3, 8].tap { |ary| ary.delete(3) }.count #=> 4
1
dgilperez

Élimination non destructive de la première occurrence:

a = [2, 4, 6, 3, 8]
n = a.index 3
a.take(n)+a.drop(n+1)
0
Lori