查找数组中最常见的字符串

Ju *_*ira 20 ruby arrays string

我有这个数组,例如(大小是可变的):

   x = ["1.111", "1.122", "1.250", "1.111"]
Run Code Online (Sandbox Code Playgroud)

我需要找到最常用的值("1.111"在这种情况下).

有一个简单的方法吗?

事先提前!


编辑#1:谢谢大家的答案!


编辑#2:我根据ZED的信息更改了我接受的答案.再次感谢大家!

Way*_*rad 43

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"
Run Code Online (Sandbox Code Playgroud)

注意:Enumberable.max_byRuby 1.9是新的,但它已被反向移植到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
Run Code Online (Sandbox Code Playgroud)

作为猴子补丁

或者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"
Run Code Online (Sandbox Code Playgroud)


the*_*Man 5

一次通过哈希来累积计数.使用.max()查找具有最大值的哈希条目.

#!/usr/bin/ruby

a = Hash.new(0)
["1.111", "1.122", "1.250", "1.111"].each { |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

require 'benchmark'

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
end

n = 1000
Benchmark.bm(20) do |x|
  x.report("Hash.new(0)") do
    n.times do 
      a = Hash.new(0)
      ary.each { |num| a[num] += 1 }
      a.max{ |a,b| a[1] <=> b[1] }.first
    end 
  end

  x.report("inject:") do
    n.times do
      ary.inject(Hash.new(0)){ |h,i| h[i] += 1; h }.max{ |a,b| a[1] <=> b[1] }.first
    end
  end

  x.report("most_common_value():") do
    n.times do
      most_common_value(ary)
    end
  end
end

结果如下:

                          user     system      total        real
Hash.new(0)           2.150000   0.000000   2.150000 (  2.164180)
inject:               2.440000   0.010000   2.450000 (  2.451466)
most_common_value():  1.080000   0.000000   1.080000 (  1.089784)