Code block for element comparison in an array?

I’m new to Ruby and I can’t think of how to do this! I would like each
element in an array to compare itself with all its proceeding elements.

For example:

In an array of 10 elements,
a[0] will be compared to a[1] … a[9]
a[1] will be compared to a[2] … a[9]

a[9] will not be compared, as there is nothing larger than it.

For those who don’t understand, I think the Java/C++ equivalent would
be:

for(int i=0; i < array.length; i++) {
for(int j=i+1; j < array.length; j++) {
// Compare array[i] with array[j]
}
}

On 13.12.2009 12:27, Derek C. wrote:

For those who don’t understand, I think the Java/C++ equivalent would
be:

for(int i=0; i< array.length; i++) {
for(int j=i+1; j< array.length; j++) {
// Compare array[i] with array[j]
}
}

Just translate this directly to Ruby and you have your solution. Hint:
you can use Fixnum#upto.

Kind regards

robert

Just translate this directly to Ruby and you have your solution. Hint:
you can use Fixnum#upto.

Kind regards

robert

I thought Ruby does not have a for loop. Am I wrong? If it doesn’t, I
don’t know how to do this.

Ah, I figured it out… For anyone who is interested the answer is:

for i in 0…array.length-1
for j in i+1…array.length-1
// Comparison here!
end
end

On Dec 13, 2009, at 3:27 AM, Derek C. wrote:

for(int i=0; i < array.length; i++) {
for(int j=i+1; j < array.length; j++) {
// Compare array[i] with array[j]
}
}

Here are a couple ways I could think to do it…

#method 1
a.length.times do |i|
(i+1).upto(a.length) do |j|
# Compare a[i] and a[j]
end
end

#method 2
a.each_with_index do |e1,i|
a[(i+1)…a.length].each do |e2|
# Compare e1 and e2
end
end


Jose Hales-Garcia
UCLA Department of Statistics
[email protected]

Here the solution with Integer#upto(n), as mentioned by Robert.

0.upto(array.length-1) { |i|
(i+1).upto(array.length-1) { |j|
// Comparison here!
}
}

And the first loop could be replace by array.length.times { |i| }
Or even better, array.each_index { |i| }

That looks more rubyish …

P.S.: You can use 0…array.length instead of 0…array.length-1

2009/12/13 Derek C. [email protected]

On 2009-12-13, Derek C. [email protected] wrote:

I’m new to Ruby and I can’t think of how to do this! I would like each
element in an array to compare itself with all its proceeding elements.

Why?

For those who don’t understand, I think the Java/C++ equivalent would
be:

for(int i=0; i < array.length; i++) {
for(int j=i+1; j < array.length; j++) {
// Compare array[i] with array[j]
}
}

I notice that you don’t DO anything with the comparison. What’s the
point? If you’re trying to verify that the array is sorted, you can
do this with a LOT fewer operations…

-s

Derek C. wrote:

Ah, I figured it out… For anyone who is interested the answer is:

for i in 0…array.length-1
for j in i+1…array.length-1
// Comparison here!
end
end

It would be more Rubyish to make the outer loop an each_with_index, I
think.

Best,
–Â
Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Thanks everyone for the information! :smiley:

Benoit D. wrote:

P.S.: You can use 0…array.length instead of 0…array.length-1

Ah, thanks very much! That is very clever.

Seebs wrote:

On 2009-12-13, Derek C. [email protected] wrote:

I’m new to Ruby and I can’t think of how to do this! I would like each
element in an array to compare itself with all its proceeding elements.

Why?

I’m making a scheduler for my college courses! First, it picks out the
courses I need to take (based on what is being offered that semester)
and stores it in an array. Then it checks the array, comparing the
elements to all the others, and picks out classes are no more than 30
minutes apart from each other. (That’s why I’ve got to compare all of
the elements.)

An example output looks like this so far:

MONDAY/WEDNESDAY: VALID COURSE COMBINATIONS
ITEC 3860 => “Software Development I” with [Dr. XYZ] (12:0-13:45)
ITEC 3200 => “Intro to Databases” with [Dr. ABC] (14:0-15:15)
*** OR ***
ITEC 4820 => “Info Technology Project II” with [Dr. Lil’teapot]
(12:0-13:45)
ITEC 3200 => “Intro to Databases” with [Mr. Nodoctorate] (14:0-15:15)

It’s been a fun project to help familiarize me with Ruby!

Derek C.:

First, it picks out the courses I need to take (based on what is being
offered that semester) and stores it in an array. Then it checks the
array, comparing the elements to all the others

Then you might be interested in Array#combination:

classes = [‘devel’, ‘databases’, ‘IT’]
classes.combination(2).each do |a, b|
puts “comparing #{a} with #{b}”
end

comparing devel with databases
comparing devel with IT
comparing databases with IT

— Shot

Jose Hales-Garcia wrote:

#method 2
a.each_with_index do |e1,i|
a[(i+1)…a.length].each do |e2|
# Compare e1 and e2
end
end

a[(i+1)…a.length].each
^ That blew my mind Jose!

On 13.12.2009 16:13, Derek C. wrote:

Jose Hales-Garcia wrote:

#method 2
a.each_with_index do |e1,i|
a[(i+1)…a.length].each do |e2|
# Compare e1 and e2
end
end

a[(i+1)…a.length].each
^ That blew my mind Jose!

It’s a bit inefficient as it will create n intermediate Arrays. Also,
the range should be (i+1) … a.length (i.e. excluding a.length).
Here’s a variant which does not create all the intermediate sub arrays:

a.each_with_index do |e, i|
for j in i+1 … a.length
puts “compare #{e} to #{a[j]}”
end
end

Here are more solutions with less math (no “i+1”):

a.each_with_index do |e, i|
for j in 0 … i
puts “compare #{e} to #{a[j]}”
end
end

a.each_with_index do |e, i|
i.times do |j|
puts “compare #{e} to #{a[j]}”
end
end

Note, these does compare in a different order.

Of course there are a lot more variants… :slight_smile:

Cheers

robert

On Dec 13, 2009, at 10:35 AM, Robert K. wrote:

It’s a bit inefficient as it will create n intermediate Arrays.

Aren’t they Copy on Write though?

James Edward G. II