查找数组中最常见的字符串
我有这个数组,例如(大小是可变的):
x = ["1.111", "1.122", "1.250", "1.111"]
我需要找到最常用的值(在这种情况下为"1.111"
)。
有一个简单的方法吗?
事先提前!
编辑#1:谢谢大家的答案!
编辑#2:我根据ZED的信息更改了我接受的答案。 再次感谢大家!
Ruby <2.2
#!/usr/bin/ruby1.8 def most_common_value(a) a.group_by do |e| e end.values.max_by(&:size).first end x = ["1.111", "1.122", "1.250", "1.111"] p most_common_value(x) # => "1.111"
注意: Enumberable.max_by
是Ruby 1.9的新增function,但它已被Enumberable.max_by
移植到1.8.7
Ruby> = 2.2
Ruby 2.2引入了Object#本身方法,通过它我们可以使代码更简洁:
def most_common_value(a) a.group_by(&:itself).values.max_by(&:size).first end
作为猴子补丁
或者作为Enumerable#mode
:
Enumerable.class_eval do def mode group_by do |e| e end.values.max_by(&:size).first end end ["1.111", "1.122", "1.250", "1.111"].mode # => "1.111"
一次通过哈希来累积计数。 使用.max()查找具有最大值的哈希条目。
#!的/ usr / bin中/ruby a = Hash.new(0) [“1.111”,“1.122”,“1.250”,“1.111”]。每个{| num | a [num] + = 1 } a.max {| a,b | a [1] <=> b [1]}#=> [“1.111”,2]
或者,将它们全部卷成一行:
ary.inject(Hash.new(0)){| h,i | h [i] + = 1; h} .max {| a,b | a [1] <=> b [1]}#=> [“1.111”,2]
如果你只想要重新添加项目.first():
ary.inject(Hash.new(0)){| h,i | h [i] + = 1; h} .max {| a,b | a [1] <=> b [1]} .first#=>“1.111”
我使用的第一个样本是如何在Perl中完成的。 第二个是Ruby-ish。 两者都适用于旧版本的Ruby。 我想比较它们,再看看Wayne的解决方案如何加快速度,所以我测试了基准:
#!/ usr / bin / env ruby 要求'基准' ary = [“1.111”,“1.122”,“1.250”,“1.111”] * 1000 def most_common_value(a) a.group_by {| e | e} .values.max_by {| values | values.size} .first 结束 n = 1000 Benchmark.bm(20)do | x | x.report(“Hash.new(0)”)做 n次 a = Hash.new(0) ary.each {| num | a [num] + = 1} a.max {| a,b | a [1] <=> b [1]} .first 结束 结束 x.report(“inject:”)做 n次 ary.inject(Hash.new(0)){| h,i | h [i] + = 1; h} .max {| a,b | a [1] <=> b [1]} .first 结束 结束 x.report(“most_common_value():”)做 n次 most_common_value(元) 结束 结束 结束
结果如下:
用户系统总真实 Hash.new(0)2.150000 0.000000 2.150000(2.164180) 注入:2.440000 0.010000 2.450000(2.451466) most_common_value():1.080000 0.000000 1.080000(1.089784)
您可以对数组进行排序,然后循环一次。 在循环中,只需跟踪当前项目及其显示的次数。 列表结束或项目更改后,如果count > max_count
,则设置max_count == count
。 当然要跟踪哪个项目有max_count
。
您可以创建一个hashmap,将数组项存储为键,其值是元素在数组中出现的次数。
伪代码:
["1.111", "1.122", "1.250", "1.111"].each { |num| count=your_hash_map.get(num) if(item==nil) hashmap.put(num,1) else hashmap.put(num,count+1) }
如前所述,排序可能会更快。
使用散列的默认值function:
>> x = ["1.111", "1.122", "1.250", "1.111"] >> h = Hash.new(0) >> x.each{|i| h[i] += 1 } >> h.max{|a,b| a[1] <=> b[1] } ["1.111", 2]
它将返回数组中最受欢迎的值
x.group_by{|a| a }.sort_by{|a,b| b.size<=>a.size}.first[0]
IE:
x = ["1.111", "1.122", "1.250", "1.111"] # Most popular x.group_by{|a| a }.sort_by{|a,b| b.size<=>a.size}.first[0] #=> "1.111 # How many times x.group_by{|a| a }.sort_by{|a,b| b.size<=>a.size}.first[1].size #=> 2