Eu, pessoalmente, como [1, 2, 3, 4, 5] - [3]o que resulta em => [1, 2, 4, 5]partir irb.
Travis
24
E se houver várias entradas de 3 e quisermos excluir apenas uma delas? (Isto está relacionado tão perguntando isso aqui poderia ser melhor)
Navneet
113
Apenas um aviso de que .delete () retornará o valor excluído, não a matriz modificada com o valor removido.
Joshua Pinter
23
A outra consequência a considerar é que deletemodifica 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.
Srt32
2
@ user3721428, delete (3) não se refere ao elemento na posição 3, mas exclui qualquer elemento correspondente ao número inteiro 3. Ele removerá todas as ocorrências de 3 e não tem nada a ver com o índice ou a posição das matrizes.
bkunzi01
226
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.
Como srt32 aponta na resposta, há uma distinção importante a ser feita entre usar .deletee -. .deleteretornará 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.
Argus9
5
array - subArraynão funcionará para Matriz de matrizes , mas array.delete(subArray)funcionará.
Sachin
20
A diferença muito importante entre [1,2,3] - [2]e [1,2,3].delete(2)é que o deletemétodo modifica a matriz original , enquanto [1,2,3] - [3]cria uma nova matriz .
Timothy Kovalev
Re subarrays (comentário de @ Sachin acima) "Claro que sim", você só precisa acertar a notação: [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
Eu estava procurando uma maneira de fazer isso e excluir apenas uma instância do elemento no caso de duplicatas e isso funciona muito bem!
Xeroshogun 10/10
Eu acho que esta resposta está errada, simplesmente porque arr.index () poderia irnil
windmaomao 15/01
32
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'.
@Zac, claro, mas essa resposta já foi mencionado (como tem a muito concisa -=maneira a-=[4]ie a=a-[4]. [3,4]-[4], Que eu disse que gostava), mas eu queria mencionar uma outra maneira possível.
Barlop #
Este método também tem a vantagem de retornar a matriz em vez do elemento excluído.
require 'fruity'classArraydef rodrigo_except(*values)self- values
enddef niels_except value
value = value.kind_of?(Array)? value :[value]self- value
endend
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:
classArraydef rodrigo_except(*values)self- values
enddef niels_except value
value = value.kind_of?(Array)? value :[value]self- value
endend
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:
classArraydef rodrigo_except(*values)self- values
enddef niels_except value
value = value.kind_of?(Array)? value :[value]self- value
endend
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
Sua solução não funciona no irbconsola 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>
hgsongra
11
Para declarar no IRB, você precisa adicionar o método à Matriz class Array; def except(*values); self - values; end; end.
Mark Swardstrom
3
Você também pode consertar o macaco. Eu nunca entendi por que Ruby tem um exceptmétodo para, Hashmas não para Array:
classArraydef except value
value = value.kind_of(Array)? value :[value]self- value
endend
Você não precisa do value.kind_of(Array)teste. Apenas use self - Array(value).
precisa saber é o seguinte
3
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.
Se você também deseja tornar essa operação de exclusão encadeada, para poder excluir algum item e continuar encadeando operações na matriz resultante, use tap:
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 controladoractive record
métododelete
Respostas:
Eu acho que descobri:
fonte
[1, 2, 3, 4, 5] - [3]
o que resulta em=> [1, 2, 4, 5]
partirirb
.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:
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.
fonte
.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 , masarray.delete(subArray)
funcionará.[1,2,3] - [2]
e[1,2,3].delete(2)
é que odelete
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]
. :-)Outra opção:
o que resulta em
fonte
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
Poderia haver uma maneira mais simples. Não estou dizendo que essa é uma prática recomendada, mas é algo que deve ser reconhecido.
fonte
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:
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
fonte
eu gosto de
-=[4]
maneira mencionada em outras respostas para excluir os elementos cujo valor é 4.Mas existe esta maneira:
mencionado em algum lugar em " Operações básicas de matriz ", depois de mencionar a
map
funçãofonte
.delete(6)
-=
maneiraa-=[4]
iea=a-[4]
.[3,4]-[4]
, Que eu disse que gostava), mas eu queria mencionar uma outra maneira possível.Você pode simplesmente executar:
fonte
Um
.delete_at(3)
3
aqui sendo a posição.fonte
Aqui estão alguns benchmarks:
E novamente com uma matriz maior contendo muitas duplicatas:
E ainda maior com mais duplicatas:
fonte
Melhorei a solução da Niels
Agora você pode usar
fonte
irb
consola2.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 paraArray
:Agora você pode fazer:
Ou:
fonte
value.kind_of(Array)
teste. Apenas useself - 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:
fonte
Remoção não destrutiva da primeira ocorrência:
fonte
Se você também deseja tornar essa operação de exclusão encadeada, para poder excluir algum item e continuar encadeando operações na matriz resultante, use
tap
:fonte
Compilando todas as opções diferentes para excluir em ruby
fonte