Code block for element comparison in an array?

D

Derek Cannon

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 with array[j]
}
}
 
R

Robert Klemme

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 with array[j]
}
}


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

Kind regards

robert
 
D

Derek Cannon

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.
 
D

Derek Cannon

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
 
S

Seebs

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 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
 
J

Jose Hales-Garcia

[Note: parts of this message were removed to make it a legal post.]


for(int i=0; i < array.length; i++) {
for(int j=i+1; j < array.length; j++) {
// Compare array 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 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
(e-mail address removed)
 
B

Benoit Daloze

[Note: parts of this message were removed to make it a legal post.]

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
 
M

Marnen Laibow-Koser

Derek said:
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
(e-mail address removed)
 
D

Derek Cannon

Seebs said:

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!
 
D

Derek Cannon

Thanks everyone for the information! :D

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

Ah, thanks very much! That is very clever.
 
D

Derek Cannon

Jose said:
#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!
 
R

Robert Klemme

Jose said:
#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... :)

Cheers

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top