我有
a = ["a", "d", "c", "b", "b", "c", "c"]
并且需要打印类似的东西(按出现次数降序排序):
c:3
b:2
我了解第一部分(发现非唯一)是:
b = a.select{ |e| a.count(e) > 1 }
=> ["c", "b", "b", "c", "c"]
或者
puts b.select{|e, c| [e, a.count(e)] }.uniq
c
b
如何输出每个非唯一且出现次数向后排序?
puts a.uniq.
map { | e | [a.count(e), e] }.
select { | c, _ | c > 1 }.
sort.reverse.
map { | c, e | "#{e}:#{c}" }
该group_by方法经常用于此目的:
a.group_by{ |i| 一世 }
{
“一个” => [
[0] “一”
],
“d” => [
[0] "d"
],
"c" => [
[0] "c",
[1] "c",
[2] "c"
],
"b" => [
[0] "b",
[1] “乙”
]
}
我喜欢:
a.group_by{ |i| i }.each_with_object({}) { |(k,v), h| h[k] = v.size }
{
“一” => 1,
"d" => 1,
"c" => 3,
"b" => 2
}
或者:
哈希[a.group_by{ |i| i }.map{ |k,v| [k, v.size] }]
{
“一” => 1,
"d" => 1,
"c" => 3,
"b" => 2
}
其中之一可能会抓挠你的痒。从那里你可以使用一个小测试来减少结果:
哈希[a.group_by{ |i| i }.map{ |k,v| v.size > 1 && [k, v.size] }]
{
"c" => 3,
"b" => 2
}
如果您只想打印信息,请使用:
将 a.group_by{ |i| i }.map{ |k,v| "#{k}: #{v.size}" }
一个:1
d: 1
三:3
乙:2
怎么样:
a.sort.chunk{|x| a.count(x)}.sort.reverse.each do |n, v|
puts "#{v[0]}:#{n}" if n > 1
end
我个人喜欢这个解决方案:
a.inject({}) {|hash, val| hash[val] ||= 0; hash[val] += 1; hash}.
reject{|key, value| value == 1}.sort.reverse.
each_pair{|k,v| puts("#{k}:#{v}")}
从 Ruby 2.7 开始,您可以使用Enumerable#tally和编号的块参数:
a = ["a", "d", "c", "b", "b", "c", "c"]
puts a.tally.filter { _2 > 1 }.sort_by { -_2 }.map &:first
在这里,Enumerable#tally返回一个类似于 的哈希{ 'a' => 1, 'b' => 2, ... },然后您必须对其进行过滤和排序。排序后,哈希将折叠为嵌套数组,例如[['b', 2], ...]. 最后一步是获取每个数组元素的第一个参数,使用&:first.
这会给你一个哈希element => occurrences:
b.reduce(Hash.new(0)) do |hash, element|
hash[element] += 1
hash
end
puts a.uniq.
map { |e| a.count(e) > 1 ? [e, a.count(e)] : nil }.compact.
sort { |a, b| b.last <=> a.last }
a.reduce(Hash.new(0)) { |memo,x| memo[x] += 1; memo } # Frequency count.
.select { |_,count| count > 1 } # Choose non-unique items.
.sort_by { |x| -x[1] } # Sort by number of occurrences descending.
# => [["c", 3], ["b", 2]]
还:
a.group_by{|x|x}.map{|k,v|[k,v.size]}.select{|x|x[1]>1}.sort_by{|x|-x[1]}
# => [["c", 3], ["b", 2]]