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]
   }
}

···

--
Posted via http://www.ruby-forum.com/.

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

Kind regards

  robert

···

On 13.12.2009 12:27, Derek Cannon 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.

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]
    }
}

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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
jose@stat.ucla.edu

···

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

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

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

···

On 2009-12-13, Derek Cannon <novellterminator@gmail.com> wrote:
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
| Seebs.Net <-- lawsuits, religion, and funny pictures
Fair game (Scientology) - Wikipedia <-- get educated!

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.

···

--
Posted via http://www.ruby-forum.com/\.

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

···

On 2009-12-13, Derek Cannon <novellterminator@gmail.com> wrote:

--
Posted via http://www.ruby-forum.com/\.

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!

···

--
Posted via http://www.ruby-forum.com/\.

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

···

--
Posted via http://www.ruby-forum.com/.

Derek Cannon:

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

···

--
Not all code needs to be a factory, some of it can just be origami.
                                                             [_why]

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 13.12.2009 16:13, Derek Cannon 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!

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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 Cannon <novellterminator@gmail.com>

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

--
Posted via http://www.ruby-forum.com/\.

Derek Cannon 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
marnen@marnen.org
--
Posted via http://www.ruby-forum.com/\.

Aren't they Copy on Write though?

James Edward Gray II

···

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

On 13.12.2009 16:13, Derek Cannon 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.

Thanks everyone for the information! :smiley:

Benoit Daloze wrote:

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

Ah, thanks very much! That is very clever.

···

--
Posted via http://www.ruby-forum.com/\.