Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check that all elements of one array are greater than their counterparts in a parallel array (in Ruby).

Tags:

ruby

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.

like image 275
Darcys22 Avatar asked Mar 22 '14 04:03

Darcys22


2 Answers

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.

like image 81
Michael Kohl Avatar answered Sep 22 '22 22:09

Michael Kohl


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.

like image 37
Jake Romer Avatar answered Sep 26 '22 22:09

Jake Romer