在Ruby中从数组中移除前导零元素

4

我有一个像这样的数组:

a = [0, 0, 1, 0, 1, 1, 0]

我想要去掉开头的0,得到以下结果:
a = [1, 0, 1, 1, 0]

什么是在Ruby中实现此操作的最佳方法?我已经想出了一个解决方案,但它感觉不够优雅:
count = 0
a.each do |element|
  break if element != 0
  count += 1
end
a = a[count..-1]

我觉得这个问题可能有一个简洁的一行代码解决方案。

我添加了一个可能会引起兴趣的基准测试。 - Cary Swoveland
4个回答

6

我会使用:

 [0, 0, 1, 0, 1, 1, 0].drop_while(&:zero?)
 #=> [1, 0, 1, 1, 0]

2

1
非常好。谢谢您先生。a = a.drop_while {|x| x == 0} - inersha
@matt 很有趣,但是不是手术语法 drop_while 吗?性能更好还是更差? - Kick Buttowski
我添加了一个可能会引起兴趣的基准测试。 - Cary Swoveland

2
until a[0] != 0 do a.shift end

我添加了一个可能会引起兴趣的基准测试。 - Cary Swoveland

1
"为了速度,我会把钱投资在以下方面。"(保留HTML标签)
def drop_leading_zeros(arr)
  i = arr.index(1)
  i.nil? ? arr : arr[i..-1]
end

drop_leading_zeros [0, 0, 1, 0, 1, 1, 0]  #=> [1, 0, 1, 1, 0] 
drop_leading_zeros [0, 0, 0, 0, 0, 0, 0]  #=> [] 

让我们进行基准测试。

require 'fruity'

def test(n)
  arr = Array.new(n-1, 0) << 1
  puts
  compare do
    matt        { a = arr.dup; a.drop_while { |x| x == 0} }
    spickermann { a = arr.dup; a.drop_while(&:zero?) }
    Jürgen      { a = arr.dup; a.shift until a[0] != 0; a }
    Cary        { a = arr.dup; i = a.index(1); i.nil? ? a : a[i..-1] }
  end
end

test(n) 比较了一个大小为 n 的数组的四个计算,其中最后一个元素等于 1,而其他所有元素都等于 0。我已经在每个代码片段中包含了 a = arr.dup,因为如果不这样做,有些人会改变 arr

test(3)
Running each test 16384 times. Test will take about 1 second.
Jürgen is faster than matt by 30.000000000000004% ± 10.0%
matt is similar to Cary
Cary is similar to spickermann

test(10)
Running each test 8192 times. Test will take about 1 second.
Cary is faster than Jürgen by 30.000000000000004% ± 10.0%
Jürgen is faster than matt by 19.999999999999996% ± 10.0%
matt is faster than spickermann by 10.000000000000009% ± 10.0%

test(1_000)
Running each test 512 times. Test will take about 2 seconds.
Cary is faster than Jürgen by 5x ± 0.1
Jürgen is faster than matt by 10.000000000000009% ± 1.0%
matt is similar to spickermann

test(10_000)
Running each test 64 times. Test will take about 2 seconds.
Cary is faster than Jürgen by 6x ± 0.1
Jürgen is faster than matt by 10.000000000000009% ± 1.0%
matt is similar to spickermann

test(100_000)
Running each test 4 times. Test will take about 1 second.
Cary is faster than Jürgen by 6x ± 0.1
Jürgen is faster than matt by 10.000000000000009% ± 1.0%
matt is similar to spickermann

test(1_000_000)
Running each test once. Test will take about 3 seconds.
Cary is faster than Jürgen by 6x ± 0.1
Jürgen is faster than matt by 10.000000000000009% ± 1.0%
matt is similar to spickermann

1
非常有趣。似乎你必须在可读性和性能之间做出选择... - spickermann
@spickerman,我原本以为index会很快,因为它是通过参数而不是块来调用的。 - Cary Swoveland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接