wake-up-neo.com

Wie kann ich ein Element nach Wert aus einem Array löschen?

Ich habe eine Reihe von Elementen in Ruby

[2,4,6,3,8]

Ich muss zum Beispiel Elemente mit dem Wert 3 entfernen

Wie mache ich das?

294
Tamik Soziev

Ich glaube, ich habe es herausgefunden:

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

Ausleihen von Travis in den Kommentaren ist dies eine bessere Antwort:

Ich persönlich mag [1, 2, 7, 4, 5] - [7] was => [1, 2, 4, 5] aus irb ergibt

Ich habe seine Antwort modifiziert, da 3 das dritte Element in seinem Beispiel-Array war. Dies kann zu Verwirrung für diejenigen führen, die nicht erkennen, dass sich 3 im Array auf Position 2 befindet. 

190
Abram

Andere Option:

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

a -= [3]

was in ... resultiert

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

Ich bin nicht sicher, ob jemand dies angegeben hat, aber Array.delete () und - = value werden jede Instanz des Werts löschen, der innerhalb des Arrays übergeben wird. Um die erste Instanz des bestimmten Elements zu löschen, können Sie etwas tun

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

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

Es könnte einen einfacheren Weg geben. Ich sage nicht, dass dies die beste Praxis ist, aber es sollte etwas anerkannt werden.

33
Scott

Ich mag den in anderen Antworten erwähnten -=[4]-Weg, um die Elemente zu löschen, deren Wert 4 ist.

Aber es gibt diesen Weg:

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

irgendwo in " Basic Array Operations " erwähnt, nachdem die map-Funktion erwähnt wurde.

24
barlop

Angenommen, Sie möchten 3 nach Wert an mehreren Stellen in einem Array löschen, Ich denke, die Ruby-Methode für diese Aufgabe wäre die delete_if-Methode:

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

Sie können delete_if auch zum Entfernen von Elementen im Szenario "Array von Arrays" verwenden.

Hoffe, das löst Ihre Anfrage

20
Sayan

Sie können einfach ausführen:

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

Ein .delete_at(3)3 ist hier die Position.

18
Sawo Cliff

Hier sind einige Benchmarks:

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

Und wieder mit einem größeren Array, das viele Duplikate enthält:

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

Und noch größer mit mehr Duplikaten:

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

Ich habe die Lösung von Niels verbessert

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

Jetzt können Sie verwenden

[1, 2, 3, 4].except(3, 4) # return [1, 2]
[1, 2, 3, 4].except(4)    # return [1, 2, 3]
6

Sie können es auch mit einem Affen patchen. Ich habe nie verstanden, warum Ruby eine except Methode für Hash hat, aber nicht für Array

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

Jetzt können Sie tun:

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

Oder:

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

Wenn Sie also mehrere Vorkommen von 3 haben und nur das erste Vorkommen von 3 löschen möchten, können Sie einfach folgende Schritte ausführen.

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

Wenn Sie diese Löschoperation auch verketten lassen möchten, um ein Element zu löschen und die Operationen für das resultierende Array fortzusetzen, verwenden Sie tap 

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

Zerstörungsfreie Beseitigung des ersten Vorkommens:

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