У меня есть массив элементов в Ruby
[2,4,6,3,8]
Мне нужно удалить элементы со значением, 3
например
Как я могу это сделать?
active record
методаdelete
У меня есть массив элементов в Ruby
[2,4,6,3,8]
Мне нужно удалить элементы со значением, 3
например
Как я могу это сделать?
active record
методаdelete
Ответы:
Я думаю, что я понял это:
a = [3, 2, 4, 6, 3, 8]
a.delete(3)
#=> 3
a
#=> [2, 4, 6, 8]
[1, 2, 3, 4, 5] - [3]
результаты которого в => [1, 2, 4, 5]
с irb
.
delete
мутирует базовый массив, тогда как -
создает новый массив (который вам возвращается) без удаленного значения. В зависимости от вашего варианта использования любой подход может иметь смысл.
Занимая у Тревиса в комментариях, это лучший ответ:
Я лично , как
[1, 2, 7, 4, 5] - [7]
в результате чего=> [1, 2, 4, 5]
изirb
Я изменил его ответ, увидев, что 3 был третьим элементом в его массиве примеров. Это может привести к некоторой путанице для тех, кто не понимает, что 3 находится в позиции 2 в массиве.
.delete
и -
. .delete
вернет значение, удаленное из массива, если оно есть; -
не буду. Так [ 1, 2, 3 ] - [ 2 ]
что вернется [ 1, 3 ]
, пока [ 1, 2, 3 ].delete( 2 )
вернется 2
.
array - subArray
не будет работать для Array of Arrays , но array.delete(subArray)
будет работать.
[1,2,3] - [2]
и [1,2,3].delete(2)
заключается в том, что delete
метод изменяет исходный массив , в то время как [1,2,3] - [3]
создает новый массив .
[1,2,[2],2,3,4] - [2]
дает вам [1, [2], 3, 4]
, но [1,2,[2],2,3,4] - [[2]]
дает вам [1, 2, 2, 3, 4]
. :-)
Я не уверен, что кто-то это сказал, но Array.delete () и - = value будут удалять каждый экземпляр значения, переданного ему в массиве. Чтобы удалить первый экземпляр определенного элемента, вы можете сделать что-то вроде
arr = [1,3,2,44,5]
arr.delete_at(arr.index(44))
#=> [1,3,2,5]
Там может быть более простой способ. Я не говорю, что это лучшая практика, но это то, что следует признать.
nil
Предполагая, что вы хотите удалить 3 по значению в нескольких местах в массиве, я думаю, что рубиновым способом решения этой задачи будет использование метода delete_if:
[2,4,6,3,8,3].delete_if {|x| x == 3 }
Вы также можете использовать delete_if для удаления элементов в сценарии «массив массивов».
Надеюсь, что это решит ваш запрос
Мне нравится -=[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>
упоминается где-то в « Базовых операциях с массивами », после него упоминается map
функция.
.delete(6)
-=
способ, a-=[4]
т a=a-[4]
. Е., Который [3,4]-[4]
, как я сказал, мне понравился), но я хотел бы упомянуть другой возможный способ.
А .delete_at(3)
3
здесь существо позиции.
Вот несколько тестов:
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
Я улучшил решение Нильса
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
консоли 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>
class Array; def except(*values); self - values; end; end
.
Вы также можете обезьяна исправить это. Я никогда не понимал, почему у Ruby есть 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)
.
Поэтому, когда у вас есть несколько вхождений 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.
Компилирование всех различных опций для удаления в ruby
delete - удаляет совпадающие элементы по значению Если найдено более одного значения, оно удалит все. Если вы не заботитесь о количестве вхождений или уверены в единственном вхождении, используйте этот метод.
a = [2, 6, 3, 5, 3, 7]
a.delete(3) # returns 3
puts a # return [2, 6, 5, 7]
delete_at - удаляет элемент по указанному индексу. Если вы знаете индекс, используйте этот метод.
# continuing from the above example
a.delete_at(2) # returns 5
puts a # returns [2, 6, 7]
delete_if - удаляет каждый элемент, для которого блок имеет значение true. Это изменит массив. Массив изменяется мгновенно при вызове блока.
b = [1, 2, 5, 4, 9, 10, 11]
b.delete_if {|n| n >= 10}. # returns [1, 2, 5, 4, 9]
reject - это вернет новый массив с элементами, для которых данный блок имеет значение false. Порядок поддерживается с этим.
c = [1, 2, 5, 4, 9, 10, 11]
c.reject {|n| n >= 10}. # returns [1, 2, 5, 4, 9]
отказаться! - так же, как delete_if . Массив может не меняться мгновенно при вызове блока.
Если вы хотите удалить несколько значений из массива, лучший вариант - ниже.
a = [2, 3, 7, 4, 6, 21, 13]
b = [7, 21]
a = a - b # a - [2, 3, 4, 6, 13]
delete
array.delete(3)
не работает внутри ruby на контроллере рельсов