如何计算数组中的多个值

时间:2016-05-13 02:43:55

标签: arrays ruby

我可以使用Array#count计算一个值。

numbers = [1, 2, 5, 5, 1, 3, 1, 2, 4, 3]
numbers.count(1) #=> 3

如何计算数组中的多个值?

我写的是:

numbers.count(1) + numbers.count(2) #=> 5
[1,2].map{|i| numbers.count(i)}.sum #=> 5

我认为这些有点多余。

3 个答案:

答案 0 :(得分:7)

count也可以占用一个块,所以你可以用一次只遍历数组的方式来编写它:

numbers.count {|i| [1,2].include? i } # => 5

或者为了好玩,以更实用的/ point-free风格:

numbers.count &[1,2].method(:include?) # => 5

答案 1 :(得分:2)

你的意思是这样的吗?

[1, 2, 2, 3, 3, 3, 4, 4, 4, 4].count_all(3, 4) # => 7

虽然Ruby的核心库中没有直接提供该功能的东西,但添加它是非常简单的。

您可以编写辅助方法:

def count_all(array, values_to_count)
  array.count { |el| values_to_count.include?(el) }
end

count_all([1, 2, 2, 3, 3, 3, 4, 4, 4, 4], [3, 4]) # => 7

您可以使用Ruby的新refinements在需要时向Array添加方法:

module ArrayExtensions
  refine Array do
    def count_all(*values_to_count)
      self.count { |el| values_to_count.include?(el) }
    end
  end
end

# Then inside some module or class

using ArrayExtensions

[1, 2, 2, 3, 3, 3, 4, 4, 4, 4].count_all(3, 4) # => 7

或者您可以选择采用更为苛刻的路径并直接修改Array

class Array
  def count_all(*values_to_count)
    self.count { |el| values_to_count.include?(el) }
  end
end

[1, 2, 2, 3, 3, 3, 4, 4, 4, 4].count_all(3, 4) # => 7

答案 2 :(得分:1)

numbers = [1, 2, 5, 5, 1, 3, 1, 2, 4, 3]
numbers_to_count = [1, 2]

numbers.size - (numbers - numbers_to_count).size
  #=> 5

我们有

n = numbers.size
  #=> 10 
a = (numbers - numbers_to_count)
  #=> [5, 5, 3, 4, 3] 
m = a.size
  #=> 5 
n - m
  #=> 5

require 'fruity'

n = 1e6
numbers = Array.new(n) { rand(100) }
  #=> [21, 78, 20, 98,..., 41, 87, 57] 
numbers.size
  #=> 1000000
numbers_to_count = (0..99).to_a.sample(20)
  #=> [80, 61, 43, 84, 16, 65, 7, 98, 59, 6,
  #    58, 49, 1, 9, 94, 56, 13, 67, 22, 68]     

compare do 
  _jtb1 { numbers.count {|i| numbers_to_count.include? i } }
  _jtb2 { numbers.count &numbers_to_count.method(:include?) }
  _cary { numbers.size - (numbers - numbers_to_count).size }
end

Running each test once. Test will take about 9 seconds.
_cary is faster than _jtb1 by 5x ± 1.0
_jtb1 is faster than _jtb2 by 10.000000000000009% ± 10.0%

考虑到Array#-是用C编码的,这并不奇怪。

我没有对@ faraz的方法进行基准测试,因为它们似乎与@ jtbandes'相似。

相关问题