我可以使用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
我认为这些有点多余。
答案 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'相似。