With ruby, I am trying to look from the first array key[:nb].value, if there is one similar pair in the second one.
Considerate below arrays contain thousands of elements:
arr1 = [{"nb"=>"5df54g54df", "active"=>true, "brand"=>"aisle"},{"nb"=>"5jghfj264", "active"=>false, "brand"=>"leg"},{"nb"=>"5qwercv546", "active"=>true, "brand"=>"gem"}]
arr2 = [{"nb"=>"5df54g54df", "active"=>true, "brand"=>"aisle"},{"nb"=>"5jghfj264", "active"=>false, "brand"=>"leg"}]
So far I was thinking something like that :
p (arr1.map(&:nb).find do |nb, val| arr2.map(&:nb)).include?(nb && val)
Would you have a suggestion, please?
CodePudding user response:
How about something like this? See comments below:
arr1 = [{ 'nb' => '5df54g54df', 'active' => true, 'brand' => 'aisle' }, { 'nb' => '5jghfj264', 'active' => false, 'brand' => 'leg' },
{ 'nb' => '5qwercv546', 'active' => true, 'brand' => 'gem' }]
arr2 = [{ 'nb' => '5df54g54df', 'active' => true, 'brand' => 'aisle' },
{ 'nb' => '5jghfj264', 'active' => false, 'brand' => 'leg' }]
p(
arr1.select do |h| # Select all objects from arr1, that return true in block:
arr2.any? { |h2| h['nb'] == h2['nb'] } #Any element from arr2 that contains equal `'nb'` keys.
end
)
#=> [{"nb"=>"5df54g54df", "active"=>true, "brand"=>"aisle"}, {"nb"=>"5jghfj264", "active"=>false, "brand"=>"leg"}]
CodePudding user response:
require 'set'
arr2_nb_vals = arr2.each_with_object(Set.new) do |h,arr2_nb_vals|
arr2_nb_vals << h["nb"]
end
#=> #<Set: {"5df54g54df", "5jghfj264"}>
arr1.select { |h| arr2_nb_vals.include?(h["nb"]) }
#=> [{"nb"=>"5df54g54df", "active"=>true, "brand"=>"aisle"},
# {"nb"=>"5jghfj264", "active"=>false, "brand"=>"leg"}]
By first collecting the values of h["nb"]
, h
in arr2
, into a set, the calculation arr2_nb_vals.include?(h["nb"])
is very fast, nearly independent of arr2_nb_vals.size
.
That makes the computational complexity close to O(arr1.size arr2.size)
, as compared with O(arr1.size**2)
when arr2_nb_vals.include?(h["nb"])
is replaced with arr2.include?(h["nb"])
.