I am trying to compare two arrays to ensure that the corresponding values of one is always greater than the other.
a = [2, 3, 4]
b = [1, 2, 3]
# a[0] > b[0] ... a[x] > b[x]
At this point I am thinking of using inject with an index and return if the comparison fails, like:
b.each_with_index.inject(true) do |cmp, (element,index)|
if element > a[index] do
cmp = false
return
end
end
Is there a better way of doing this? Kinda feeling like Ruby or Rails might already have something like this built-in and I missed it.
This is what I would do:
a.zip(b).all? { |a, b| a > b }
Note though that zip will truncate in case the two arrays are not of the same size.
If it's safe to assume both arrays are of the same size, here's a method that'll keep memory usage and running time to a minimum:
(0...a.length).all?{ |i| a[i] > b[i] }
#=> true
while also being extendable to an arbitrary number of arrays:
(0...a.length).all?{ |i| a[i] > [b[i], c[i], d[i]].max }
To illustrate the relative resource-intensity of the zip versus the range approach, take arrays a and b, each with length n = 5_000.
Here's the best case, where a[0] < b[0] is false:
user system total real
zip: 0.350000 0.000000 0.350000 ( 0.351115)
range: 0.000000 0.000000 0.000000 ( 0.000509)
and the worst, where only a[n-1] > b[n-1] is false:
user system total real
zip: 0.760000 0.000000 0.760000 ( 0.752424)
range: 0.420000 0.000000 0.420000 ( 0.421132)
[Here's the benchmark script]
zip creates a new array out of the two (or more) you pass into it, which gets expensive for large n.
That said, the zip approach is easier to read and more idiomatic Ruby, so if scaling isn't a concern I would use that one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With