Nesting Array loops

I new to Ruby and I have lost touch with whatever little programming I
did know a few years back. Sorry if this is a lame question.

How does one nest arrays?

I want to check every element of the array and compare it against rest
of the elements of that array for repeat occurences. but for now I did
be happy if I can get to even print the 2 values, hence 'puts #i, #j' in
the code.

  f = File.open("iplist.txt")
  f1 = File.open("iplist.txt")
  f.each { |i|
    f1.each { |j|
     puts "#{i}, #{j}"
   }
}

With the above code I only get output of one successful iteration of
f.each and it stops and doesnt continue for the rest of the values of
f.each.

Surprisingly this works...

  (0..5).each { |i|
    (0..4).each { |j|
     puts "#{i}, #{j}"
   }
}

00
01
02
03
04
05
10
11
12
......etc

whats the difference between the codes thats causing this error? They
are both arrays aint it?

Thanks. :slight_smile:

···

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

Those aren't arrays, they are files. You can't assume
that enumerable objects can be iterated more than once.

You can reopen the file with each iteration or you can
use File#rewind to 'back up' to the beginning of the file:

f = File.open("iplist.txt")
f.each { |i|
   File.open("iplist.txt") { |f1|
     f1.each { |j|
       puts "#{i.chomp}, #{j.chomp}"
     }
   }
}

f = File.open("iplist.txt")
f1 = File.open("iplist.txt")
f.each { |i|
   f1.each { |j|
     puts "#{i.chomp}, #{j.chomp}"
   }
   f1.rewind
}

···

On Apr 9, 2007, at 2:49 AM, Rubic wrote:

want to check every element of the array and compare it against rest
of the elements of that array for repeat occurences. but for now I did
be happy if I can get to even print the 2 values, hence 'puts #i, #j' in
the code.

  f = File.open("iplist.txt")
  f1 = File.open("iplist.txt")
  f.each { |i|
    f1.each { |j|
     puts "#{i}, #{j}"
   }
}

Rubic wrote:

I new to Ruby and I have lost touch with whatever little programming I
did know a few years back. Sorry if this is a lame question.

How does one nest arrays?

One possibility:
array = [ ["foo", "bar"], ["baz", 42] ]

I want to check every element of the array and compare it against rest
of the elements of that array for repeat occurences. but for now I did
be happy if I can get to even print the 2 values, hence 'puts #i, #j' in
the code.

  f = File.open("iplist.txt")

irb(main):011:0> f.class
=> File

  f1 = File.open("iplist.txt")

irb(main):011:0> f1.class
=> File

  f.each { |i|
    f1.each { |j|
     puts "#{i}, #{j}"
   }
}

If you want an Array, use File#readlines. This produces an array of all lines in a file (including the \n at the end of each line), and you can iterate over them. For example:

C:\>ruby test.rb
line1,line1
line1,line2
line1,line3
line2,line1
line2,line2
line2,line3
line3,line1
line3,line2
line3,line3

C:\>cat test.rb
#Create Arrays for the files:
f = File.readlines("test.txt")
f1 = File.readlines("test.txt")

#Iterate over the Arrays:
f.each do |i|
   f1.each do |j|
     puts "#{i.chomp},#{j.chomp}"
   end
end

With the above code I only get output of one successful iteration of
f.each and it stops and doesnt continue for the rest of the values of
f.each.

Probably because you have one big string in the file, and thus only one object the block can iterate.
But without sample data, I can't say more, really.

Surprisingly this works...

  (0..5).each { |i|
    (0..4).each { |j|
     puts "#{i}, #{j}"
   }
}

[snip]

whats the difference between the codes thats causing this error? They
are both arrays aint it?

0..5 and 0..4 are Ranges, not Arrays, and thus #each iterates over each element of the Range.

···

--
Phillip "CynicalRyan" Gawlowski
http://cynicalryan.110mb.com/

Rule of Open-Source Programming #7:

Release early, release often. Clean compilation is optional.

The problem is that both f and f1 are pointing to the same disk file. After the first iteration using f, the disk file is at EOF. When f1 attempts to iterate further, it sees the EOF and terminates.

If you read the whole file into an array, your approach will work:

<code>
f = File.read("/Users/mg/Desktop/test.txt")
f = f.map { |e| e.chomp } # get rid on newlines
puts f
puts
f.each do |i|
    f.each { |j| puts "#{i}, #{j}" }
end
</code>

<result>
quick
fox
brown
fox

quick, quick
quick, fox
quick, brown
quick, fox
fox, quick
fox, fox
fox, brown
fox, fox
brown, quick
brown, fox
brown, brown
brown, fox
fox, quick
fox, fox
fox, brown
fox, fox
</result>

However, to go back to your original problem of detecting duplicates, there are better ways. Here is one:

<code>
# Array#uniq removes duplicates.

def has_dups?(ary)
    ary.size != ary.uniq.size
end

f = File.read("/Users/mg/Desktop/test.txt")
f = f.map { |e| e.chomp } # get rid on newlines
has_dups?(f) # => true
has_dups?(f.uniq) # => false
</code>

Regards, Morton

···

On Apr 9, 2007, at 2:49 AM, Rubic wrote:

I new to Ruby and I have lost touch with whatever little programming I
did know a few years back. Sorry if this is a lame question.

How does one nest arrays?

I want to check every element of the array and compare it against rest
of the elements of that array for repeat occurences. but for now I did
be happy if I can get to even print the 2 values, hence 'puts #i, #j' in
the code.

  f = File.open("iplist.txt")
  f1 = File.open("iplist.txt")
  f.each { |i|
    f1.each { |j|
     puts "#{i}, #{j}"
   }
}

With the above code I only get output of one successful iteration of
f.each and it stops and doesnt continue for the rest of the values of
f.each.