code_junkie

Ruby: How to find item in array which has the most occurrences?

Nov 13th, 2011
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.50 KB | None | 0 0
  1. [1, 1, 1, 2, 3]
  2. => 1
  3.  
  4. ['cat', 'dog', 'snake', 'dog']
  5. => dog
  6.  
  7. arr = [1, 1, 1, 2, 3]
  8. freq = arr.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
  9. arr.sort_by { |v| freq[v] }.last
  10.  
  11. require 'benchmark'
  12.  
  13. class Array
  14. def mode1
  15. sort_by {|i| grep(i).length }.last
  16. end
  17. def mode2
  18. freq = inject(Hash.new(0)) { |h,v| h[v] += 1; h }
  19. sort_by { |v| freq[v] }.last
  20. end
  21. def mode3
  22. freq = inject(Hash.new(0)) { |h,v| h[v] += 1; h }
  23. max = freq.values.max # we're only interested in the key(s) with the highest frequency
  24. freq.select { |k, f| f == max } # extract the keys that have the max frequency
  25. end
  26. end
  27.  
  28. arr = Array.new(1_000) { |i| rand(100) } # something to test with
  29.  
  30. Benchmark.bm(30) do |r|
  31. res = {}
  32. (1..3).each do |i|
  33. m = "mode#{i}"
  34. r.report(m) do
  35. 100.times do
  36. res[m] = arr.send(m).inspect
  37. end
  38. end
  39. end
  40. res.each { |k, v| puts "%10s = %s" % [k, v] }
  41. end
  42.  
  43. user system total real
  44. mode1 34.375000 0.000000 34.375000 ( 34.393000)
  45. mode2 0.359000 0.000000 0.359000 ( 0.359000)
  46. mode3 0.219000 0.000000 0.219000 ( 0.219000)
  47. mode1 = 41
  48. mode2 = 41
  49. mode3 = [[41, 17], [80, 17], [72, 17]]
  50.  
  51. def mode4
  52. group_by{|i| i}.max{|x,y| x[1].length <=> y[1].length}[0]
  53. end
  54.  
  55. ========================== IronRuby =====================================
  56. (iterations bumped to **1000**) user system total real
  57. mode1 (I didn't bother :-))
  58. mode2 4.265625 0.046875 4.312500 ( 4.203151)
  59. mode3 0.828125 0.000000 0.828125 ( 0.781255)
  60. mode4 1.203125 0.000000 1.203125 ( 1.062507)
  61.  
  62. class Array
  63. def mode4
  64. group_by{|i| i}.max{|x,y| x[1].length <=> y[1].length}[0]
  65. end
  66. end
  67.  
  68. user system total real
  69. mode1 24.340000 0.070000 24.410000 ( 24.526991)
  70. mode2 0.200000 0.000000 0.200000 ( 0.195348)
  71. mode3 0.120000 0.000000 0.120000 ( 0.118200)
  72. mode4 0.050000 0.010000 0.060000 ( 0.056315)
  73. mode1 = 76
  74. mode2 = 76
  75. mode3 = [[76, 18]]
  76. mode4 = 76
  77.  
  78. arr = [1, 1, 1, 2, 3]
  79. arr.sort_by { |e| arr.grep(e).size }.last # => 1
  80.  
  81. class Array
  82. def mode
  83. sort_by {|i| grep(i).length }.last
  84. end
  85. end
  86.  
  87. idx = {}
  88. [2,2,1,3,1].each { |i| idx.include?(i) ? idx[i] += 1 : idx[i] = 1}
  89.  
  90. group_by { |n| n }.values.max_by(&:size).first
  91.  
  92. class Array
  93. def mode1
  94. group_by { |n| n }.values.max_by(&:size).first
  95. end
  96. def mode2
  97. freq = inject(Hash.new(0)) { |h,v| h[v] += 1; h }
  98. max = freq.values.max # we're only interested in the key(s) with the highest frequency
  99. freq.select { |k, f| f == max } # extract the keys that have the max frequency
  100. end
  101. end
  102.  
  103. arr = Array.new(1_0000) { |i| rand(100000) } # something to test with
  104.  
  105. Benchmark.bm(30) do |r|
  106. (1..2).each do |i| r.report("mode#{i}") { 100.times do arr.send("mode#{i}").inspect; end }; end
  107. end
  108.  
  109. user system total real
  110. mode1 1.830000 0.010000 1.840000 ( 1.876642)
  111. mode2 2.280000 0.010000 2.290000 ( 2.382117)
  112. mode1 = 70099
  113. mode2 = [[70099, 3], [70102, 3], [51694, 3], [49685, 3], [38410, 3], [90815, 3], [30551, 3], [34720, 3], [58373, 3]]
  114.  
  115. def mode
  116. group_by {|x| x}.group_by {|k,v| v.size}.sort.last.last.map(&:first)
  117. end
Add Comment
Please, Sign In to add comment