如何从一个数组中按值删除一个元素

我有一个Ruby中的元素数组

[2,4,6,3,8]

我需要移除值为3的元素,例如

我怎么做呢?

对该问题的评论 (2)
解决办法

我想我已经明白了:

a = [2,4,6,3,8]
a.delete(3)
评论(8)

借用评论中Travis的说法,这是一个更好的答案:

我个人喜欢[1, 2, 7, 4, 5] - [7],结果是=> [1, 2, 4, 5],来自irb

我修改了他的答案,看到3是他例子中数组的第三个元素。这可能会给那些没有意识到3在数组中处于第2位的人带来一些困惑

评论(4)

另一个选择:

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

a -= [3]

这导致了

=> [2, 4, 6, 8] 
评论(0)

我'不知道是否有人说过,但Array.delete()和-= value将删除Array中传递给它的值的每个实例。 为了删除特定元素的第一个实例,你可以做如下操作

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

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

可以有一个更简单的方法。 我'不是说这是最佳做法,但这是应该被认可的。

评论(1)

假设你想在一个数组中多处按值删除3。 我认为 ruby 的方法是使用 delete_if 方法来完成这个任务。

[2,4,6,3,8,3].delete_if {|x| x == 3 } 

你也可以在'array of arrays'的情况下使用delete_if来删除元素。

希望这能解决你的疑问

评论(0)

我喜欢其他答案中提到的-=[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>

在"[基本数组操作][1]"中的某个地方提到了 "map "函数。

[1]: https://rubymonk.com/learning/books/1-ruby-primer/chapters/1-arrays/lessons/34-arrays-the-basics

评论(3)

你可以直接跑。

[2,4,6,3,8].delete(3)
评论(0)

.delete_at(3)``3这里是指位置。

评论(0)

下面是一些基准。

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
评论(1)

我改进了Niels'的解决方案

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]
评论(2)

你也可以给它打补丁。 我一直不明白为什么Ruby对 "Hash "有一个 "except "方法,而对 "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]
评论(1)

因此,当你有多个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.
评论(0)

如果你也想让这个删除操作成为可链式操作,这样你就可以删除某个项目,然后继续对结果数组进行链式操作,请使用tap

[2, 4, 6, 3, 8].tap { |ary| ary.delete(3) }.count #=> 4
评论(0)

首次发生的非破坏性清除。

a = [2, 4, 6, 3, 8]
n = a.index 3
a.take(n)+a.drop(n+1)
评论(0)