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

时间:2012-04-05 19:19:18

标签: arrays ruby

我在Ruby中有一系列元素

[2,4,6,3,8]

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

我该怎么做?

15 个答案:

答案 0 :(得分:429)

我想我已经明白了:

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

答案 1 :(得分:201)

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

  

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

我修改了他的答案,看到3是他的示例数组中的第三个元素。对于那些没有意识到3在数组中位置2的人来说,这可能会导致一些混淆。

答案 2 :(得分:63)

另一种选择:

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

a -= [3]

导致

=> [2, 4, 6, 8] 

答案 3 :(得分:35)

我不确定是否有人说过这个,但是Array.delete()和 - = value 将删除Array中传递给它的每个值的实例。为了删除特定元素的第一个实例,您可以执行类似

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

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

可能有一种更简单的方法。我并不是说这是最佳做法,但它应该被认可。

答案 4 :(得分:24)

我喜欢其他答案中提到的-=[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>
在提及map函数之后,在" Basic Array Operations"中提到了

答案 5 :(得分:22)

假设您要在数组中的多个位置按值删除3, 我认为执行此任务的ruby方法是使用delete_if方法:

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

您还可以使用delete_if删除“数组数组”场景中的元素。

希望这可以解析您的查询

答案 6 :(得分:19)

您只需运行:

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

答案 7 :(得分:19)

这里有.delete_at(3) 3位置。

答案 8 :(得分:12)

以下是一些基准:

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

答案 9 :(得分:7)

我改进了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]

答案 10 :(得分:3)

你也可以修补它。我从未理解为什么Ruby对except有一个Hash方法而对Array没有{<1}}:

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]

答案 11 :(得分:2)

因此,当您有多次出现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.

答案 12 :(得分:2)

如果您还希望使此删除操作可链接,以便可以删除某些项目并继续对结果数组进行链接操作,请使用tap

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

答案 13 :(得分:2)

编译用于在ruby中删除的所有不同选项

删除-按值删除匹配的元素。如果多个值匹配,它将全部删除。如果您不在乎出现的次数或确定只发生一次,请使用此方法。

a = [2, 6, 3, 5, 3, 7]
a.delete(3)  # returns 3
puts a       # return [2, 6, 5, 7]

delete_at -删除给定索引处的元素。如果您知道索引,请使用此方法。

# continuing from the above example
a.delete_at(2) # returns 5
puts a         # returns [2, 6, 7]

delete_if -删除每个块为true的元素。这将修改数组。调用该块时,数组立即发生变化。

b = [1, 2, 5, 4, 9, 10, 11]
b.delete_if {|n| n >= 10}.  # returns [1, 2, 5, 4, 9]

拒绝-这将返回带有给定块为false的元素的新数组。以此维护订单。

c = [1, 2, 5, 4, 9, 10, 11]
c.reject {|n| n >= 10}.  # returns [1, 2, 5, 4, 9]

拒绝!-与 delete_if 相同。调用该块时,数组可能不会立即更改。

如果要从数组中删除多个值,最好的选择如下。

a = [2, 3, 7, 4, 6, 21, 13]
b = [7, 21]
a = a - b    # a - [2, 3, 4, 6, 13]

答案 14 :(得分:1)

无损清除首次出现:

/