Cómo puedo eliminar un elemento de una matriz por valor


Tengo una matriz de elementos en Ruby

[2,4,6,3,8]

Necesito eliminar elementos con valor 3 por ejemplo

¿Cómo hago eso?

 280
Author: the Tin Man, 2012-04-05

13 answers

Creo que lo he descubierto:

a = [2,4,6,3,8]
a.delete(3)
 399
Author: Tamik Soziev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-04 03:10:33

Tomando prestado de Travis en los comentarios, esta es una mejor respuesta:

Personalmente me gusta [1, 2, 7, 4, 5] - [7] que resulta en => [1, 2, 4, 5] de irb

Modifiqué su respuesta viendo que 3 era el tercer elemento en su matriz de ejemplo. Esto podría llevar a cierta confusión para aquellos que no se dan cuenta de que 3 está en la posición 2 en la matriz.

 179
Author: Abram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-28 00:26:54

Otra opción:

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

a -= [3]

Que resulta en

=> [2, 4, 6, 8] 
 57
Author: Steve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-18 02:23:43

No estoy seguro si alguien ha declarado esto, pero Array.delete () y - = value eliminarán cada instancia del valor que se le pase dentro del Array. Para eliminar la primera instancia del elemento en particular, podría hacer algo como

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

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

Podría haber una manera más simple. No estoy diciendo que esto sea una buena práctica, pero es algo que debe ser reconocido.

 27
Author: Scott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-31 18:29:36

Me gusta la forma -=[4] mencionada en otras respuestas para eliminar los elementos cuyo valor es 4.

Pero hay esta manera:

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

Mencionado en algún lugar en " Operaciones Básicas de matriz", después de mencionar la función map.

 22
Author: barlop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-28 23:32:03

A .delete_at(3) 3 aquí está la posición.

 18
Author: Sawo Cliff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-28 12:08:44

Simplemente puede ejecutar:

[2,4,6,3,8].delete(3)
 15
Author: rilutham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-28 23:29:47

Suponiendo que desea eliminar 3 por valor en varios lugares de una matriz, Creo que la forma ruby de hacer esta tarea sería usar 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 'array of arrays'.

Espero que esto resuelva su consulta

 13
Author: Sayan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-27 13:47:19

Aquí hay algunos puntos de referencia:

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

Y de nuevo con una matriz más grande que contiene muchos duplicados:

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

Y aún más grande con más duplicados:

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
 10
Author: the Tin Man,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-28 23:50:11

Mejoré la solución de Niels

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

Ahora puedes usar

[1, 2, 3, 4].except(3, 4) # return [1, 2]
[1, 2, 3, 4].except(4)    # return [1, 2, 3]
 6
Author: Rodrigo Mendonça,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-20 14:06:21

También puedes parchearlo. Nunca entendí por qué Ruby tiene un método except para Hash pero no para Array:

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

Ahora puedes hacer:

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

O:

[1,3,7,"436",354,nil].except([354, 1]) #=> [3,7,"436",nil]
 3
Author: Niels Kristian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-28 23:30:13

Así que cuando tienes múltiples ocurrencias de 3 y solo quieres eliminar la primera ocurrencia de 3, simplemente puedes hacer algo como se muestra a continuación.

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.
 2
Author: ashan priyadarshana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-27 10:01:12

Eliminación no destructiva de la primera ocurrencia:

a = [2, 4, 6, 3, 8]
n = a.index 3
a.take(n)+a.drop(n+1)
 0
Author: Lori,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-18 02:07:03