使用true/false值数组选择数组元素的最佳方法是什么?

Ste*_*eve 0 ruby arrays

我有两个数组:

a = [1, 2, 3, 4]
b = [true, true, false, false]
Run Code Online (Sandbox Code Playgroud)

选择a其对应元素的元素的最佳方法btrue什么?在这个例子中,我期望:

result = [1, 2]
Run Code Online (Sandbox Code Playgroud)

我是这样做的:

zipped = a.zip(b)
zipped.select{ |z| z[1] }.map{ |n| n.first }
# => [1, 2]
Run Code Online (Sandbox Code Playgroud)

我想知道纯Ruby中的最佳解决方案,但我也愿意接受GSL等的建议.

表现:

array_size = 4000
iterations = 1000

Benchmark.bm do |bm|
  bm.report do
    iterations.times do
      a.each_with_index.map { |a, i| a if b[i] }.compact
    end
  end
end

Benchmark.bm do |bm|
  bm.report do
    iterations.times do
      zipped = a.zip(b).select{ |z| z[1] }.map{ |n| n.first }
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

下面的表现说明,不仅是mapeach_with_index更具可读性,而且也快于大型阵列.

     user     system      total        real
   0.610000   0.000000   0.610000 (  0.608642)
       user     system      total        real
   0.880000   0.000000   0.880000 (  0.882018)
Run Code Online (Sandbox Code Playgroud)

ste*_*lag 11

将布尔值转换为枚举器 - 没有zip,也没有数组查找.

a = [1,2,3,4]
b = [true, true, false, false].to_enum

a.select{b.next}  # => [1, 2]
Run Code Online (Sandbox Code Playgroud)

  • 有趣的解决方案,但它要么修改`b`,要么需要一个额外的变量来保存枚举器.您可以只调用`a.select {b.shift}`而不是将`b`转换为枚举器. (8认同)
  • 优雅辉煌. (3认同)

Jör*_*tag 6

我发现它非常易读,并且清楚地表达了语义.

a.select.with_index {|_, i| b[i] }
Run Code Online (Sandbox Code Playgroud)

事实证明,@ steenslag以更优雅的方式击败了我4分钟:-D