Big array, problems with deleting all empty items

it seems that I have to run it a couple different times for it to
work… array.length = 16576, if that could be a potential problem. if
it is, how do I work around it?

077:0> array = File.read("/text.txt").to_a.each { |x| x.chomp! }
080:0> array.each_with_index { |x,y|
array.delete_at(y) if x.empty? == true
}

still leaves me with plenty of empty array items
080:0> array[-3]
“”

077:0> array = File.read("/text.txt").to_a.each { |x| x.chomp! }
080:0> array.each_with_index { |x,y|
array.delete_at(y) if x.empty? == true
}

still leaves me with plenty of empty array items
080:0> array[-3]
“”

I think that might be due to the fact that you’re removing elements from
an
array that is still being iterated on.
If element 3 is empty, and element 4 is empty, you’re deleting element
three
in one loop iteration. At that moment, former element 4 now becomes
element
3. Your iteration jumps to element 4, effectively skipping that empty
element, never checking it.

Maybe simply use:
array.delete("")

To delete all objects in the array that are equal to “”.

If you need something more fancy, use:
array.delete_if{|item| block}

With a block that evaluates to true for every item you want to delete.

HTH,

Felix

On 15.10.2007 19:41, Simon S. wrote:

080:0> array[-3]
“”

Your bug is in the loop: you iterate and delete at the same time which
will likely yield strange results (as you observe). Why don’t you just
do

array.delete_if {|x| x.empty?}

Btw, empty? == true is quite dangerous because in Ruby “true” is not the
only valid value for true.

Apart from that it seems your code is pretty inefficient since you do a
lot copying around. I’d rather do this

ar = []
File.foreach(“text.txt”) do |line|
line.chomp!
ar << line unless line.empty?
end

Cheers

robert

On Oct 15, 2007, at 12:41 PM, Simon S. wrote:

it seems that I have to run it a couple different times for it to
work… array.length = 16576, if that could be a potential problem. if
it is, how do I work around it?

077:0> array = File.read("/text.txt").to_a.each { |x| x.chomp! }

That’s better written as:

lines = File.readlines("/text.txt")
lines.each { |l| l.chomp! }

080:0> array.each_with_index { |x,y|
array.delete_at(y) if x.empty? == true
}

And this can be as simple as:

lines.delete_if { |l| l.empty? }

However, I would switch strategies and only add the lines you are
interested in to begin with:

lines = Array.new
File.foreach("/text.txt") do |line|
line.chomp!
lines << line unless line.empty?
end

I hope that helps.

James Edward G. II

Quoth Robert K.:

still leaves me with plenty of empty array items
080:0> array[-3]
“”

Your bug is in the loop: you iterate and delete at the same time which
will likely yield strange results (as you observe). Why don’t you just do

array.delete_if {|x| x.empty?}

Btw, empty? == true is quite dangerous because in Ruby “true” is not the
only valid value for true.

But !!e.empty? == true will do the trick :D.

Simon S. wrote:

077:0> array = File.read("/text.txt").to_a.each { |x| x.chomp! }
080:0> array.each_with_index { |x,y|
array.delete_at(y) if x.empty? == true
}

still leaves me with plenty of empty array items
080:0> array[-3]
“”

You are modifying the array itself while iterating through it. I haven’t
checked specifically how it behaves in your specific case, but this
approach in general needs special attention to have it right in all
cases.

I guess you sould check out *#reject instead…

mortee

Simon S. wrote:

it seems that I have to run it a couple different times for it to
work… array.length = 16576, if that could be a potential problem. if
it is, how do I work around it?

077:0> array = File.read("/text.txt").to_a.each { |x| x.chomp! }
080:0> array.each_with_index { |x,y|
array.delete_at(y) if x.empty? == true
}

still leaves me with plenty of empty array items
080:0> array[-3]
“”

Try running this code:

arr = [10, 20, 30, 40]

arr.each_with_index do |elmt, i|
puts elmt
arr.delete_at(i) if elmt == 20
end

As you can see that code tries to display every element in the array.
Does it succeed?

This convoluted code:

array = File.read("/text.txt").to_a.each { |x| x.chomp! }
array.each_with_index { |x,y|
array.delete_at(y) if x.empty? == true
}

can be done more directly doing something like this:

arr = []

IO.foreach(“data.txt”) do |line|
if line != “\n”
arr << line.chomp
end
end

puts arr

On 15.10.2007 20:38, Konrad M. wrote:

But !!e.empty? == true will do the trick :D.

I’ve seen the smiley but, frankly, I find this only moderately funny.
The reason is that there are too many people around that think comparing
boolean values is a great idea. This is at least superfluous and often
outright dangerous. Other people then will have to debug those bugs…

Cheers

robert

On Oct 16, 2007, at 11:40 AM, Robert K. wrote:

array.delete_at(y) if x.empty? == true

Cheers

robert

Well, in this case it may be just naive.
In many languages you might have to do something like that.
No big deal.
Comparing a boolean method to a boolean value will only ever return a
boolean.
Can’t go wrong.

If it is set up right it could be convenient if there is a chance of
a nil value, because nil == true returns false.
But the condition is still in .empty?

Simon S. wrote:

it seems that I have to run it a couple different times for it to
work… array.length = 16576, if that could be a potential problem. if
it is, how do I work around it?

077:0> array = File.read("/text.txt").to_a.each { |x| x.chomp! }
080:0> array.each_with_index { |x,y|
array.delete_at(y) if x.empty? == true
}

still leaves me with plenty of empty array items
080:0> array[-3]
“”

array = File.read(path).split(/\r?\n/)
array.delete!("")

Regards
Stefan