# Nesting Array loops

**URL:** <https://www.ruby-forum.com/t/nesting-array-loops/91442>\
**Category:** Ruby\
**Created:** [April 9, 2007, 8:49am UTC](https://www.ruby-forum.com/t/nesting-array-loops/91442 "2007-04-09T08:49:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rubic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ec9cab/32.png) [@Rubic](https://www.ruby-forum.com/u/Rubic)\
**Post date:** [April 9, 2007, 8:49am UTC](https://www.ruby-forum.com/t/nesting-array-loops/91442/1 "2007-04-09T08:49:07Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Rubic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ec9cab/32.png) [@Rubic](https://www.ruby-forum.com/u/Rubic)\
**Post date:** [April 9, 2007, 9:00am UTC](https://www.ruby-forum.com/t/nesting-array-loops/91442/2 "2007-04-09T09:00:08Z")

</div>

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

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

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  
}

---

<div class="post-metadata">

**Author:** ![Rubic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ec9cab/32.png) [@Rubic](https://www.ruby-forum.com/u/Rubic)\
**Post date:** [April 9, 2007, 9:16am UTC](https://www.ruby-forum.com/t/nesting-array-loops/91442/3 "2007-04-09T09:16:10Z")

</div>

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/](http://cynicalryan.110mb.com/)

Rule of Open-Source Programming #7:

Release early, release often. Clean compilation is optional.

---

<div class="post-metadata">

**Author:** ![Rubic](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ec9cab/32.png) [@Rubic](https://www.ruby-forum.com/u/Rubic)\
**Post date:** [April 9, 2007, 9:51am UTC](https://www.ruby-forum.com/t/nesting-array-loops/91442/4 "2007-04-09T09:51:11Z")

</div>

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

> f.each and it stops and doesnt continue for the rest of the values of  
> f.each.

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:

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

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

`
# 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
`

Regards, Morton
