Answers:
我想我已经知道了:
a = [3, 2, 4, 6, 3, 8]
a.delete(3)
#=> 3
a
#=> [2, 4, 6, 8]
[1, 2, 3, 4, 5] - [3]
这结果=> [1, 2, 4, 5]
从irb
。
delete
对基础数组进行了突变,而-
创建了一个新数组(返回给您),但没有删除值。根据您的用例,这两种方法都可能有意义。
从Travis的评论中借用,这是一个更好的答案:
我个人喜欢
[1, 2, 7, 4, 5] - [7]
这是=> [1, 2, 4, 5]
由irb
看到3是示例数组中的第三个元素,我修改了他的答案。对于那些没有意识到3在数组中的位置2的人来说,这可能会引起一些困惑。
.delete
和之间有一个重要的区别-
。.delete
将返回从数组中删除的值(如果有);-
将不会。所以[ 1, 2, 3 ] - [ 2 ]
会回来[ 1, 3 ]
,而[ 1, 2, 3 ].delete( 2 )
会回来2
。
array - subArray
不适用于Array of Arrays,但array.delete(subArray)
可以。
[1,2,3] - [2]
和之间的非常重要的区别[1,2,3].delete(2)
是该delete
方法在创建新数组的同时修改了原始数组。[1,2,3] - [3]
[1,2,[2],2,3,4] - [2]
给您[1, [2], 3, 4]
,但是[1,2,[2],2,3,4] - [[2]]
给您[1, 2, 2, 3, 4]
。:-)
我不确定是否有人说过这一点,但是Array.delete()和-= value将删除Array中传递给它的值的每个实例。为了删除特定元素的第一个实例,您可以执行以下操作
arr = [1,3,2,44,5]
arr.delete_at(arr.index(44))
#=> [1,3,2,5]
可能有一种更简单的方法。我并不是说这是最佳做法,但这是应该认识的。
nil
我喜欢-=[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
。
.delete(6)
-=
方式, a-=[4]
即a=a-[4]
。 [3,4]-[4]
,我说我很喜欢),但是我想提及另一种可能的方式。
以下是一些基准:
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
我改进了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]
irb
控制台上运行 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>
class Array; def except(*values); self - values; end; end
。
您也可以用猴子修补它。我从来不明白为什么Ruby有一个except
方法Hash
但没有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]
value.kind_of(Array)
测试。只需使用self - Array(value)
。
编译所有不同的选项以在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]
delete
array.delete(3)
在ruby on rails controller内