class Fruit
attr_reader :name
def ==(other)
name == other.name
end
def eql?(other)
name.eql?(other.name)
end
def hash
name.hash
end
def to_s
name
end
def inspect
"#<Fruit: #{name}>"
end
private
attr_writer :name
def initialize(name)
self.name = name
end
end
Multiset[Fruit.new('apple'), Fruit.new('apple'), Fruit.new('apple'),
Fruit.new('banana'), Fruit.new('banana'), Fruit.new('pineapple')]
# => #<Multiset:#3 #<Fruit: apple>, #2 #<Fruit: banana>, #1 #<Fruit: pineapple>>
4条答案
按热度按时间nwwlzxa71#
计算这样的直方图的常用技巧是使用
Enumerable#group_by
,然后Enumerable#map
将结果Array
s转换为size
s,最后转换为Hash
:但有一个更好的方法:一个名为
MultiSet
的数据结构完全可以满足您的需求。不幸的是,在Ruby核心库或stdlib中没有一个,但是你可以找到一些实现:然而,几乎总是当你有一个数据结构,比如一个字符串的散列数组或类似的东西,那里有一个对象想要出来。毕竟,Ruby是一种面向对象的语言,而不是一种面向符号到字符串的哈希数组的语言。
iklwldmw2#
@Simone说得对,你可以使用inject方法来计算出现次数,像这样:
这在代码中并不是很清楚,但是你需要在哈希上调用
.to_i
的原因是因为如果它返回nil(即第一次遇到“apple”),你不能做nil + 1
,所以nil.to_i
变成了零。我不认为这是超级清晰的代码以上,所以我想我会提到它。虽然我的是一个“解决方案”,但Jorg在最佳实践方面是正确的,这将是一个研究OO解决方案的好机会。
balp4ylt3#
创建一个具有默认值的哈希,并遍历数组中的每个哈希:
nbnkbykc4#
输入= [{:fruit=>“apple”},{:fruit=>“apple”},{:fruit=>“apple”},{:fruit=>“banana”},{:fruit=>“banana”},{:fruit=>“pineapple”}]