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

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

···

-----Original Message-----
From: Simon Schuster [mailto:significants@gmail.com]
Sent: Monday, October 15, 2007 10:42 AM
To: ruby-talk ML
Subject: 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]
""

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 15.10.2007 19:41, Simon Schuster 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]
""

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 Gray II

···

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

Simon Schuster 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

···

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

Simon Schuster 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 Schuster 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

···

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

Quoth Robert Klemme:

···

On 15.10.2007 19:41, Simon Schuster 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]
> ""

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.

--
Konrad Meyer <konrad@tylerc.org> http://konrad.sobertillnoon.com/

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 15.10.2007 20:38, Konrad Meyer wrote:

Quoth Robert Klemme:

On 15.10.2007 19:41, Simon Schuster 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]
""

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.

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?

···

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

On 15.10.2007 20:38, Konrad Meyer wrote:

Quoth Robert Klemme:

On 15.10.2007 19:41, Simon Schuster 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]
""

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.

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