Вопрос по ruby – Как я могу удалить один элемент из массива по значению

296

У меня есть массив элементов в Ruby

<code>[2,4,6,3,8]
</code>

Мне нужно удалить элементы со значением3 например

Как я могу это сделать?

может быть связано сactive record методdelete ImranNaqvi
интересно, почемуdelete array.delete(3) не работает внутри ruby на рельсах контроллера ImranNaqvi

Ваш Ответ

14   ответов
19

.delete_at(3) 3 здесь быть позиции.

20

что вы хотите удалить 3 по значению в нескольких местах в массиве, Я думаю, что Ruby способ сделать эту задачу будет использовать метод delete_if:

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

Вы также можете использовать delete_if для удаления элементов в сценарии «массив массивов».

Надеюсь, что это решит ваш запрос

2

когда у вас есть несколько вхождений 3, и вы хотите удалить только первое вхождение 3, вы можете просто сделать что-то, как показано ниже.

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.
1

чтобы можно было удалить какой-либо элемент и продолжить операции цепочки в результирующем массиве, используйтеtap:

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

Вы можете просто запустить:

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

почему у Руби естьexcept метод дляHash но не дляArray:

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

Теперь вы можете сделать:

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

Или же:

[1,3,7,"436",354,nil].except([354, 1]) #=> [3,7,"436",nil]
Вы не нуждаетесь вvalue.kind_of(Array) тестовое задание. Просто используйтеself - Array(value).
0

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

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

Теперь вы можете использовать

[1, 2, 3, 4].except(3, 4) # return [1, 2]
[1, 2, 3, 4].except(4)    # return [1, 2, 3]
Чтобы объявить в IRB, вам нужно добавить метод в массивclass Array; def except(*values); self - values; end; end.
Ваше решение не работает наirb приставка2.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>
33

value удалит каждый экземпляр значения, переданного ему в массиве. Чтобы удалить первый экземпляр определенного элемента, вы можете сделать что-то вроде

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

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

Там может быть более простой способ. Я не говорю, что это лучшая практика, но это то, что следует признать.

Error: User Rate Limit Exceeded
192

Travis в комментариях это лучший ответ:

I personally like [1, 2, 7, 4, 5] - [7] which results in => [1, 2, 4, 5] from irb

I modified his answer seeing that 3 was the third element in his example array. This could lead to some confusion for those who don't realize that 3 is in position 2 in the array.

Error: User Rate Limit Exceeded[1,2,3] - [2]Error: User Rate Limit Exceeded[1,2,3].delete(2)Error: User Rate Limit ExceededdeleteError: User Rate Limit Exceededmodifies the original arrayError: User Rate Limit Exceeded[1,2,3] - [3]Error: User Rate Limit Exceedednew array.
array - subArrayError: User Rate Limit ExceededArray of ArraysError: User Rate Limit Exceededarray.delete(subArray)Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded.deleteError: User Rate Limit Exceeded-. .deleteError: User Rate Limit Exceeded-Error: User Rate Limit Exceeded[ 1, 2, 3 ] - [ 2 ]Error: User Rate Limit Exceeded[ 1, 3 ]Error: User Rate Limit Exceeded[ 1, 2, 3 ].delete( 2 )Error: User Rate Limit Exceeded2.
24

-=[4] Способ, упомянутый в других ответах для удаления элементов, значение которых равно 4.

Но есть такой способ:

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

упоминается где-то в & quot;Основные операции с массивами& quot ;, после упоминанияmap функция.

@ Зак конечно, но этот ответ уже упоминался (как и очень краткий-= путьa-=[4] то естьa=a-[4] . [3,4]-[4]что я сказал, что мне понравилось), но я хотел бы упомянуть еще один возможный способ.
Но вы не можете просто использовать.delete(6)
Этот метод также имеет преимущество, заключающееся в возврате массива вместо удаленного элемента.
12

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

И снова с большим массивом, содержащим много дубликатов:

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

И еще больше с большим количеством дубликатов:

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
Error: User Rate Limit Exceeded
60

Другой вариант:

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

a -= [3]

что приводит к

=> [2, 4, 6, 8] 
417

Я думаю, что я понял это:

a = [2,4,6,3,8]
a.delete(3)
Что если есть несколько записей по 3, и мы хотим удалить только одну из них? (это связано, так что лучше всего спросить здесь)
Error: User Rate Limit Exceeded
Другим следствием, которое следует учитывать, является то, чтоdelete мутирует базовый массив, тогда как- создает новый массив (который вам возвращается) без удаленного значения. В зависимости от вашего варианта использования любой подход может иметь смысл.
Мне лично нравится[1, 2, 3, 4, 5] - [3] что приводит к=> [1, 2, 4, 5] отirb.
Error: User Rate Limit Exceeded

Похожие вопросы