array2.map { |h2| array1.detect { |h1| h1[:name] == h2[:name] } }
require 'benchmark'
@array1 = [{name: "apple", quantity: 2}, {name: "grape", quantity: 10}, {name: "pear", quantity: 3}]
@array2 = [{name: "grape", freshness: 9}, {name: "apple", freshness: 7}, {name: "pear", freshness: 10}]
n = 500_000
Benchmark.bm do |x|
x.report {n.times { @array2.map { |h2| @array1.detect { |h1| h1[:name] == h2[:name] } } } }
x.report {n.times { @array1.sort_by { |x| @array2.find_index { |y| y[:name] == x[:name] } } } }
x.report {n.times { h = @array1.each_with_object({}){|e, h| h[e[:name]] = e} ; @array1 = @array2.map{|e| h[e[:name]] } } }
x.report {n.times { h = @array2.map { |e| e[:name] }.each_with_index.to_h ; @array1.sort_by { |e| h[e[:name]] } }}
x.report {n.times { @array1.each_with_object({}) { |g,h| h[g[:name]] = g }.values_at(*@array2.map { |g| g[:name] }) }}
end
user system total real
0.960000 0.000000 0.960000 ( 1.064233)
1.040000 0.020000 1.060000 ( 1.291731)
0.850000 0.000000 0.850000 ( 1.064816)
1.680000 0.000000 1.680000 ( 2.131733)
0.840000 0.000000 0.840000 ( 1.057844)
For large array, on the other hand, @sawa and @Stefan gave equally good results (added a Cary's solution):
100.times { |i| @array1 << {name:i}; @array2 << {name:i} }
@array1.shuffle!
@array2.shuffle!
user system total real
5.970000 0.000000 5.970000 ( 6.154653)
4.980000 0.010000 4.990000 ( 5.111118)
0.450000 0.010000 0.460000 ( 0.469722)
0.640000 0.010000 0.650000 ( 0.655721)
0.480000 0.010000 0.490000 ( 0.490590)