Personalmente me gusta lo [1, 2, 3, 4, 5] - [3]que resulta => [1, 2, 4, 5]de irb.
Travis
24
¿Qué sucede si hay varias entradas de 3 y queremos eliminar solo una de ellas? (esto está relacionado, por lo que preguntar aquí podría ser lo mejor)
Navneet
113
Solo un aviso de que .delete () devolverá el valor eliminado, no la matriz modificada con el valor eliminado.
Joshua Pinter
23
La otra consecuencia a considerar es que delete muta la matriz subyacente mientras que -crea una nueva matriz (que se le devuelve) sin el valor eliminado. Dependiendo de su caso de uso, cualquier enfoque puede tener sentido.
srt32
2
@ user3721428, delete (3) no se refiere al elemento en la posición 3, sino que elimina cualquier elemento que coincida con el entero 3. Eliminará todas las apariciones de 3 y no tiene nada que ver con el índice o la posición de los arrays.
bkunzi01
226
Tomando prestado de Travis en los comentarios, esta es una mejor respuesta:
Personalmente me gusta lo [1, 2, 7, 4, 5] - [7]que resulta => [1, 2, 4, 5]deirb
Modifiqué su respuesta al ver que 3 era el tercer elemento en su matriz de ejemplo. Esto podría generar cierta confusión para aquellos que no se dan cuenta de que 3 está en la posición 2 de la matriz.
Como srt32 señala en la respuesta, hay que hacer una distinción importante entre usar .deletey -. .deletedevolverá el valor que se eliminó de la matriz, si lo hay; -No lo haré. Entonces [ 1, 2, 3 ] - [ 2 ]volverá [ 1, 3 ], mientras [ 1, 2, 3 ].delete( 2 )que volverá 2.
Argus9
55
array - subArrayno funcionará para Array of Arrays , pero array.delete(subArray)lo hará.
Sachin
20
La diferencia muy importante entre [1,2,3] - [2]y [1,2,3].delete(2)es que el deletemétodo modifica la matriz original , mientras [1,2,3] - [3]crea una nueva matriz .
Timothy Kovalev el
Re subarreglos (comentario de @ Sachin arriba) "Claro que sí", solo necesitas acertar en la notación: [1,2,[2],2,3,4] - [2]te da [1, [2], 3, 4], pero [1,2,[2],2,3,4] - [[2]]te da [1, 2, 2, 3, 4]. :-)
No estoy seguro de si alguien ha dicho esto, pero Array.delete () y - = value eliminarán cada instancia del valor que se le pase dentro de Array. Para eliminar la primera instancia del elemento en particular, podría hacer algo como
Estaba buscando una manera de hacer esto y solo eliminar una instancia del elemento en caso de duplicados y ¡esto funciona muy bien!
xeroshogun
Creo que esta respuesta es incorrecta, simplemente porque arr.index () podría irnil
windmaomao
32
Suponiendo que desea eliminar 3 por valor en varios lugares de una matriz, creo que la forma rubí de hacer esta tarea sería utilizar el método delete_if:
[2,4,6,3,8,3].delete_if {|x| x ==3}
También puede usar delete_if para eliminar elementos en el escenario de 'matriz de matrices'.
@Zac por supuesto, pero esa respuesta ya se ha mencionado (al igual que la muy concisa -=manera a-=[4]es decir a=a-[4]. [3,4]-[4], Lo que he dicho me ha gustado), pero quería hablar de otra manera posible.
barlop
Este método también tiene la ventaja de devolver la matriz en lugar del elemento eliminado.
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
Y de nuevo con una matriz más grande que contiene muchos duplicados:
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
Y aún más grande con más duplicados:
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
Su solución no funciona en la 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
1
Para declarar en IRB, debe agregar el método a Array class Array; def except(*values); self - values; end; end.
Mark Swardstrom
3
También puedes mono parchearlo. Nunca entendí por qué Ruby tiene un exceptmétodo Hashpero no para Array:
classArraydef except value
value = value.kind_of(Array)? value :[value]self- value
endend
No necesitas la value.kind_of(Array)prueba. Solo úsalo self - Array(value).
Sasgorilla
3
Entonces, cuando tiene múltiples ocurrencias de 3 y solo desea eliminar la primera aparición de 3, simplemente puede hacer algo de la siguiente manera.
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.
Si también desea que esta operación de eliminación se pueda encadenar, para que pueda eliminar algún elemento y seguir encadenando operaciones en la matriz resultante, use tap:
Compilar todas las diferentes opciones para eliminar en ruby
eliminar : elimina elementos coincidentes por valor. Si más de un valor coincide, lo eliminará todo. Si no le importa la cantidad de casos o no está seguro de una sola, 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 - Elimina el elemento en el índice dado. Si conoce el índice, use este método.
# continuing from the above example
a.delete_at(2)# returns 5
puts a # returns [2, 6, 7]
delete_if : elimina todos los elementos para los que el bloque es verdadero. Esto modificará la matriz. La matriz cambia instantáneamente cuando se llama al bloque.
b =[1,2,5,4,9,10,11]
b.delete_if {|n| n >=10}.# returns [1, 2, 5, 4, 9]
rechazar - Esto devolverá una nueva matriz con los elementos para los cuales el bloque dado es falso. El orden se mantiene con esto.
c =[1,2,5,4,9,10,11]
c.reject {|n| n >=10}.# returns [1, 2, 5, 4, 9]
¡rechazar! - igual que delete_if . La matriz puede no cambiar instantáneamente cuando se llama al bloque.
Si desea eliminar varios valores de la matriz, la mejor opción es la siguiente.
a =[2,3,7,4,6,21,13]
b =[7,21]
a = a - b # a - [2, 3, 4, 6, 13]
delete
array.delete(3)
no funciona dentro de rubí en los carriles controladoractive record
métododelete
Respuestas:
Creo que lo he descubierto:
fuente
[1, 2, 3, 4, 5] - [3]
que resulta=> [1, 2, 4, 5]
deirb
.delete
muta la matriz subyacente mientras que-
crea una nueva matriz (que se le devuelve) sin el valor eliminado. Dependiendo de su caso de uso, cualquier enfoque puede tener sentido.Tomando prestado de Travis en los comentarios, esta es una mejor respuesta:
Modifiqué su respuesta al ver que 3 era el tercer elemento en su matriz de ejemplo. Esto podría generar cierta confusión para aquellos que no se dan cuenta de que 3 está en la posición 2 de la matriz.
fuente
.delete
y-
..delete
devolverá el valor que se eliminó de la matriz, si lo hay;-
No lo haré. Entonces[ 1, 2, 3 ] - [ 2 ]
volverá[ 1, 3 ]
, mientras[ 1, 2, 3 ].delete( 2 )
que volverá2
.array - subArray
no funcionará para Array of Arrays , peroarray.delete(subArray)
lo hará.[1,2,3] - [2]
y[1,2,3].delete(2)
es que eldelete
método modifica la matriz original , mientras[1,2,3] - [3]
crea una nueva matriz .[1,2,[2],2,3,4] - [2]
te da[1, [2], 3, 4]
, pero[1,2,[2],2,3,4] - [[2]]
te da[1, 2, 2, 3, 4]
. :-)Otra opción:
lo que resulta en
fuente
No estoy seguro de si alguien ha dicho esto, pero Array.delete () y - = value eliminarán cada instancia del valor que se le pase dentro de Array. Para eliminar la primera instancia del elemento en particular, podría hacer algo como
Podría haber una manera más simple. No digo que esta sea la mejor práctica, pero es algo que debería reconocerse.
fuente
nil
Suponiendo que desea eliminar 3 por valor en varios lugares de una matriz, creo que la forma rubí de hacer esta tarea sería utilizar el método delete_if:
También puede usar delete_if para eliminar elementos en el escenario de 'matriz de matrices'.
Espero que esto resuelva tu consulta
fuente
me gusta el
-=[4]
forma mencionada en otras respuestas para eliminar los elementos cuyo valor es 4.Pero hay de esta manera:
mencionado en alguna parte de " Operaciones básicas de matriz ", después de que menciona la
map
función.fuente
.delete(6)
-=
maneraa-=[4]
es decira=a-[4]
.[3,4]-[4]
, Lo que he dicho me ha gustado), pero quería hablar de otra manera posible.Simplemente puede ejecutar:
fuente
A
.delete_at(3)
3
aquí está la posición.fuente
Aquí hay algunos puntos de referencia:
Y de nuevo con una matriz más grande que contiene muchos duplicados:
Y aún más grande con más duplicados:
fuente
Mejoré la solución de Niels
Ahora puedes usar
fuente
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
.También puedes mono parchearlo. Nunca entendí por qué Ruby tiene un
except
métodoHash
pero no paraArray
:Ahora puedes hacer:
O:
fuente
value.kind_of(Array)
prueba. Solo úsaloself - Array(value)
.Entonces, cuando tiene múltiples ocurrencias de 3 y solo desea eliminar la primera aparición de 3, simplemente puede hacer algo de la siguiente manera.
fuente
Eliminación no destructiva de la primera aparición:
fuente
Si también desea que esta operación de eliminación se pueda encadenar, para que pueda eliminar algún elemento y seguir encadenando operaciones en la matriz resultante, use
tap
:fuente
Compilar todas las diferentes opciones para eliminar en ruby
fuente