Bir diziden bir öğeyi değere göre nasıl silebilirim


343

Ruby'de bir dizi elementim var

[2,4,6,3,8]

3Örneğin değeri olan öğeleri kaldırmam gerekiyor

Bunu nasıl yaparım?


i merak neden delete array.delete(3)raylar denetleyicisi üzerinde ruby ​​içinde
çalışmıyor

2
bağlı olabilir active recordyöntemedelete
ImranNaqvi

Yanıtlar:


481

Bence anladım:

a = [3, 2, 4, 6, 3, 8]
a.delete(3)
#=> 3
a
#=> [2, 4, 6, 8]

189
Ben şahsen gibi [1, 2, 3, 4, 5] - [3]hangi sonuçları => [1, 2, 4, 5]elde irb.
Travis

24
3'ün birden fazla girişi varsa ve bunlardan yalnızca birini silmek istersek ne olur? (bu, bunun en iyisi olabileceğini sormakla ilgilidir)
Navneet

113
Yalnızca .delete () öğesinin kaldırıldığı değeri değiştirilen diziyi değil, silinmiş değeri döndürür.
Joshua Pinter

23
Dikkate alınması gereken diğer sonuç delete, temel alınan diziyi -değiştirirken silinmiş değer olmadan yeni bir dizi (size döndürülen) oluşturur. Kullanım durumunuza bağlı olarak her iki yaklaşım da mantıklı olabilir.
srt32

2
@ user3721428, delete (3), konum 3'teki öğeye gönderme yapmaz, bunun yerine tamsayı 3 ile eşleşen herhangi bir öğeyi siler.
bkunzi01

226

Borçlanma Travis yorumlarında, bu daha iyi bir cevaptır:

Ben şahsen gibi [1, 2, 7, 4, 5] - [7]hangi sonuçları => [1, 2, 4, 5]eldeirb

Cevabını, 3'ün örnek dizisindeki üçüncü unsur olduğunu görünce değiştirdim. Bu, 3'ün dizide 2. konumda olduğunu bilmeyenler için biraz karışıklığa yol açabilir.


21
Srt32 yanıtta belirttiği gibi, .deleteve ile arasında önemli bir ayrım vardır -. .deleteVarsa, Diziden kaldırılan değeri döndürür; -olmaz. Böylece [ 1, 2, 3 ] - [ 2 ]dönecektir [ 1, 3 ], [ 1, 2, 3 ].delete( 2 )dönecektir 2.
Argus9

5
array - subArrayArray of Arrays için çalışmaz , ancak array.delete(subArray)çalışacaktır.
Sachin

21
Arasında çok önemli bir fark [1,2,3] - [2]ve [1,2,3].delete(2)olmasıdır deleteyöntem değiştirir orijinal dizi ederken, [1,2,3] - [3]bir oluşturur yeni bir dizi .
Timothy Kovalev

Re subarrays (@ Sachin'in yukarıdaki yorumu) "Tabii ki", gösterimi doğru yapmanız yeterlidir: [1,2,[2],2,3,4] - [2]verir [1, [2], 3, 4], ama [1,2,[2],2,3,4] - [[2]]verir [1, 2, 2, 3, 4]. :-)
Tom Hundt

69

Başka seçenek:

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

a -= [3]

sonuçlanan

=> [2, 4, 6, 8] 

50

Kimsenin bunu belirtip belirtmediğinden emin değilim, ancak Array.delete () ve - = değeri , Dizi içinde geçirilen değerin her örneğini silecektir. Belirli bir öğenin ilk örneğini silmek için aşağıdaki gibi bir şey yapabilirsiniz:

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

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

Daha basit bir yol olabilir. Bunun en iyi uygulama olduğunu söylemiyorum, ama tanınması gereken bir şey.


1
Bunu yapmak için bir yol arıyordum ve yinelenen durumlarda sadece bir örneğini silmek ve bu harika çalışıyor!
xeroshogun

Bence bu cevap yanlış, çünkü arr.index () gidebilirnil
windmaomao

32

Bir dizideki birden çok yerde 3 değerine göre silmek istediğinizi varsayarsak, bu görevi yapmanın yakut yolunun delete_if yöntemini kullanmak olacağını düşünüyorum:

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

'Dizi dizisi' senaryosundaki öğeleri kaldırırken delete_if komutunu da kullanabilirsiniz.

Umarım bu sorgunuzu çözer


25

Hoşuma gitti -=[4]Değeri 4 olan öğeleri silmek için diğer cevaplarda belirtilen yolu .

Ama bu yol var:

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

işlevden bahsettikten sonra, " Temel Dizi İşlemleri " nde bir yerde belirtilmiştir map.


Ama sadece kullanamaz mısın.delete(6)
Zac

Tabii @Zac ama şimdiden söz edilmiştir cevap (çok özlü olduğu gibi -=yol a-=[4]yani a=a-[4]. [3,4]-[4]Ben sevdim söyledi), ama başka türlü yolu hatırlatmak istedik.
barlop

Bu yöntem, silinen öğe yerine diziyi döndürme avantajına da sahiptir.
F.Webber

22

Basitçe çalıştırabilirsiniz:

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


15

İşte bazı kriterler:

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

Ve yine çok sayıda kopya içeren daha büyük bir dizi ile:

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

Ve daha fazla kopya ile daha da büyük:

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

7
Peki, en iyisi nedir? :)
Kirby

8

Niels'ın çözümünü geliştirdim

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

Şimdi kullanabilirsiniz

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

Çözümünüz irbkonsolda çalışmıyor2.2.1 :007 > [1, 2, 3, 4].except(3, 4) NoMethodError: undefined method except for [1, 2, 3, 4]:Array from (irb):7 from /usr/share/rvm/rubies/ruby-2.2.1/bin/irb:11:in <main>
hgsongra

1
IRB'de bildirmek için, yöntemi Array öğesine eklemeniz gerekir class Array; def except(*values); self - values; end; end.
Mark Swardstrom

3

Maymun yama da yapabilirsiniz. Neden Ruby için bir exceptyöntem var Hashama anlamadım hiç anlamadım Array:

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

Şimdi şunları yapabilirsiniz:

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

Veya:

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

1
value.kind_of(Array)Teste ihtiyacınız yok . Sadece kullan self - Array(value).
Sasgorilla

3

Bu nedenle, 3'ün birden çok tekrarına sahip olduğunuzda ve yalnızca 3'ün ilk tekrarını silmek istediğinizde, aşağıdaki gibi bir şey yapabilirsiniz.

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.

3

İlk oluşumun tahribatsız olarak uzaklaştırılması:

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

2

Bu silme işlemini zincirlenebilir hale getirmek istiyorsanız, bazı öğeleri silebilir ve sonuçta oluşan dizide zincirleme işlemlerine devam edebilirsiniz tap:

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

1

Ruby'de silmek için tüm farklı seçenekleri derleme

delete - Eşleşen öğeleri değere göre siler. Birden fazla değer eşleşirse tümünü kaldırır. Oluşum sayısını umursamıyorsanız veya tek bir oluşumdan emin değilseniz bu yöntemi kullanın.

a = [2, 6, 3, 5, 3, 7]
a.delete(3)  # returns 3
puts a       # return [2, 6, 5, 7]

delete_at - Belirli bir dizindeki öğeyi siler. Dizini biliyorsanız bu yöntemi kullanın.

# continuing from the above example
a.delete_at(2) # returns 5
puts a         # returns [2, 6, 7]

delete_if - Bloğunun doğru olduğu her öğeyi siler. Bu diziyi değiştirir. Dizi çağrıldığında dizi anında değişir.

b = [1, 2, 5, 4, 9, 10, 11]
b.delete_if {|n| n >= 10}.  # returns [1, 2, 5, 4, 9]

reject - Bu, verilen bloğun yanlış olduğu öğelerle yeni bir dizi döndürür. Sıralama bu şekilde yapılır.

c = [1, 2, 5, 4, 9, 10, 11]
c.reject {|n| n >= 10}.  # returns [1, 2, 5, 4, 9]

reddetmek! - delete_if ile aynı . Dizi çağrıldığında dizi anında değişmeyebilir.

Diziden birden çok değeri silmek istiyorsanız, en iyi seçenek aşağıdaki gibidir.

a = [2, 3, 7, 4, 6, 21, 13]
b = [7, 21]
a = a - b    # a - [2, 3, 4, 6, 13]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.