Nesting Array loops

R

Rubic

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. :)
 
G

Gary Wright

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

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

Phillip Gawlowski

Rubic said:
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.
 
M

Morton Goldberg

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.

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
 

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,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top