Eu tenho uma matriz de elementos em Ruby
[2,4,6,3,8]
Preciso remover elementos com valor, 3
por exemplo
Como faço isso?
active record
métododelete
Eu tenho uma matriz de elementos em Ruby
[2,4,6,3,8]
Preciso remover elementos com valor, 3
por exemplo
Como faço isso?
active record
métododelete
Respostas:
Eu acho que descobri:
a = [3, 2, 4, 6, 3, 8]
a.delete(3)
#=> 3
a
#=> [2, 4, 6, 8]
[1, 2, 3, 4, 5] - [3]
o que resulta em => [1, 2, 4, 5]
partir irb
.
delete
modifica a matriz subjacente enquanto -
cria uma nova matriz (que é retornada a você) sem o valor excluído. Dependendo do seu caso de uso, qualquer uma das abordagens pode fazer sentido.
Tomando emprestado de Travis nos comentários, esta é uma resposta melhor:
Eu pessoalmente gosto do
[1, 2, 7, 4, 5] - [7]
que resulta=> [1, 2, 4, 5]
deirb
Modifiquei sua resposta, vendo que 3 era o terceiro elemento em sua matriz de exemplo. Isso pode levar a alguma confusão para aqueles que não percebem que 3 está na posição 2 da matriz.
.delete
e -
. .delete
retornará o valor que foi removido da matriz, se houver; -
não vou. Então [ 1, 2, 3 ] - [ 2 ]
retornará [ 1, 3 ]
, enquanto [ 1, 2, 3 ].delete( 2 )
retornará 2
.
array - subArray
não funcionará para Matriz de matrizes , mas array.delete(subArray)
funcionará.
[1,2,3] - [2]
e [1,2,3].delete(2)
é que o delete
método modifica a matriz original , enquanto [1,2,3] - [3]
cria uma nova matriz .
[1,2,[2],2,3,4] - [2]
dá [1, [2], 3, 4]
, mas [1,2,[2],2,3,4] - [[2]]
dá [1, 2, 2, 3, 4]
. :-)
Não tenho certeza se alguém afirmou isso, mas Array.delete () e - = value excluirão todas as instâncias do valor passado a ele dentro da matriz. Para excluir a primeira instância do elemento específico, você pode fazer algo como
arr = [1,3,2,44,5]
arr.delete_at(arr.index(44))
#=> [1,3,2,5]
Poderia haver uma maneira mais simples. Não estou dizendo que essa é uma prática recomendada, mas é algo que deve ser reconhecido.
nil
Supondo que você deseja excluir 3 por valor em vários locais em uma matriz, acho que a maneira ruby de fazer essa tarefa seria usar o método delete_if:
[2,4,6,3,8,3].delete_if {|x| x == 3 }
Você também pode usar delete_if na remoção de elementos no cenário de 'matriz de matrizes'.
Espero que isso resolva sua consulta
eu gosto de -=[4]
maneira mencionada em outras respostas para excluir os elementos cujo valor é 4.
Mas existe esta maneira:
irb(main):419:0> [2,4,6,3,8,6].delete_if{|i|i==6}
=> [2, 4, 3, 8]
irb(main):420:0>
mencionado em algum lugar em " Operações básicas de matriz ", depois de mencionar a map
função
.delete(6)
-=
maneira a-=[4]
ie a=a-[4]
. [3,4]-[4]
, Que eu disse que gostava), mas eu queria mencionar uma outra maneira possível.
Um .delete_at(3)
3
aqui sendo a posição.
Aqui estão alguns 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
E novamente com uma matriz maior contendo muitas duplicatas:
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
E ainda maior com mais duplicatas:
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
Melhorei a solução da Niels
class Array
def except(*values)
self - values
end
end
Agora você pode usar
[1, 2, 3, 4].except(3, 4) # return [1, 2]
[1, 2, 3, 4].except(4) # return [1, 2, 3]
irb
consola 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
.
Você também pode consertar o macaco. Eu nunca entendi por que Ruby tem um except
método para, Hash
mas não para Array
:
class Array
def except value
value = value.kind_of(Array) ? value : [value]
self - value
end
end
Agora você pode fazer:
[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]
value.kind_of(Array)
teste. Apenas use self - Array(value)
.
Portanto, quando você tem várias ocorrências de 3 e deseja excluir apenas a primeira ocorrência de 3, basta fazer o seguinte:
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.
Compilando todas as opções diferentes para excluir em ruby
delete - Exclui os elementos correspondentes por valor. Se mais de um valor corresponder, ele removerá todos. Se você não se importa com o número de ocorrências ou com certeza sobre uma ocorrência única, use este método.
a = [2, 6, 3, 5, 3, 7]
a.delete(3) # returns 3
puts a # return [2, 6, 5, 7]
delete_at - Exclui o elemento no índice especificado. Se você conhece o índice, use este método.
# continuing from the above example
a.delete_at(2) # returns 5
puts a # returns [2, 6, 7]
delete_if - Exclui todos os elementos para os quais o bloco é verdadeiro. Isso modificará a matriz. A matriz muda instantaneamente conforme o bloco é chamado.
b = [1, 2, 5, 4, 9, 10, 11]
b.delete_if {|n| n >= 10}. # returns [1, 2, 5, 4, 9]
rejeitar - Isso retornará uma nova matriz com os elementos para os quais o bloco especificado é falso. A ordem é mantida com isso.
c = [1, 2, 5, 4, 9, 10, 11]
c.reject {|n| n >= 10}. # returns [1, 2, 5, 4, 9]
rejeitar! - o mesmo que delete_if . A matriz pode não mudar instantaneamente quando o bloco é chamado.
Se você deseja excluir vários valores da matriz, a melhor opção é a seguinte.
a = [2, 3, 7, 4, 6, 21, 13]
b = [7, 21]
a = a - b # a - [2, 3, 4, 6, 13]
delete
array.delete(3)
não funciona dentro de ruby on rails controlador