For example:
a = [1,2,3,4,5,6,7,8]
b = [1,9,10,11,12,13,14,15]
a
array has 1
and b
array has 1
too. So they have the same element.
How to compare them and return true
or false
with ruby?
For example:
a = [1,2,3,4,5,6,7,8]
b = [1,9,10,11,12,13,14,15]
a
array has 1
and b
array has 1
too. So they have the same element.
How to compare them and return true
or false
with ruby?
If you have many elements per Array, doing an intersection (&
) can be an expensive operation. I assume that it would be quicker to go 'by hand':
def have_same_element?(array1, array2)
# Return true on first element found that is in both array1 and array2
# Return false if no such element found
array1.each do |elem|
return true if array2.include?(elem)
end
return false
end
a = [*1..100] # [1, 2, 3, ... , 100]
b = a.reverse.to_a # [100, 99, 98, ... , 1]
puts have_same_element?(a, b)
If you know more beforehand (e.g. "array1 contains many duplicates") you can further optimize the operation (e.g. by calling uniq
or compact
first, depending on your data).
Would be interesting to see actual benchmarks.
Edit
require 'benchmark'
Benchmark.bmbm(10) do |bm|
bm.report("by hand") {have_same_element?(a, b)}
bm.report("set operation") { (a & b).empty? }
end
Rehearsal -------------------------------------------------
by hand 0.000000 0.000000 0.000000 ( 0.000014)
set operation 0.000000 0.000000 0.000000 ( 0.000095)
---------------------------------------- total: 0.000000sec
user system total real
by hand 0.000000 0.000000 0.000000 ( 0.000012)
set operation 0.000000 0.000000 0.000000 ( 0.000131)
So, in this case it looks as if the "by hand" method is really faster, but its quite a sloppy method of benchmarking with limited expressiveness.
Also, see @CarySwoveland s excellent comments about using sets, proper benchmarking and a snappier expression using find
(detect
would do the same and be more expressive imho - but carefull as it returns the value found - if your arrays contain falsey values like nil
(or false
)...; you generally want to use any?{}
here).
Intersection of two arrays can get using & operator. If you need to get similar elements in two arrays, take intersect as
a = [1,2,3,4,5,6,7,8]
b = [1,9,10,11,12,13,14,15]
and taking intersection
u = a & b
puts u
# [1]
u.empty?
# false