Question about array.each{|x| delete x}

myArray = [1, 2, 3]

puts myArray

myArray.each {|x|
if x == 1
  then puts "one"
  elsif x == 2
    then
    myArray.delete x
  elsif x == 3
    then puts "three"
  end
  }

puts myArray

The output of the above is:
1
2
3
one
1
3

And my question is "why isn't it 1 2 3 one three 1 3?". What if I wanted
to make it so?

# "why isn't it 1 2 3 one three 1 3?".

a delete (of some element) on an array will really be deleted, ergo, the elements will rearrange/move to logically occupy that deleted space.

eg,
b=[1,2,3,4,5]
#=> [1, 2, 3, 4, 5]
b.delete 2
#=> 2
b
#=> [1, 3, 4, 5]

also, array#delete(obj) will delete all elements eql to obj. see below.
now, if you combine these behaviours while walking the array itself, expect some surprises if you're not ready :slight_smile:

maybe if you show the index, ruby can help you, eg

a=[1,2,3,1,1,4]
#=> [1, 2, 3, 1, 1, 4]
a.each_with_index{|x,i| a.delete x if x==1; puts "#{i} -> #{x}"}
0 -> 1
1 -> 3
2 -> 4
#=> [2, 3, 4]

# What if I wanted to make it so?

there are many better ways, but i will just modify your sample,

myArray = [1, 2, 3]
puts myArray
myArray.delete 2 #here i delete 2 first
myArray.each {|x|
  if x == 1
    then puts "one"
  elsif x == 3
    then puts "three"
  end
}
puts myArray

1
2
3
one
three
1
3

kind regards -botp

···

From: Frisco Del Rosario [mailto:frisco@appleisp.netNO]

I just dup, like this:
myArray.dup.each {|x| ... delete from (original) myArray in
here .... }

I'm sure there are more elegant solutions, and it's a bit pants from a
performance perspective for large arrays, but it works for me.

···

On Apr 24, 10:04 am, Frisco Del Rosario <fri...@appleisp.netNO> wrote:

myArray = [1, 2, 3]

puts myArray

myArray.each {|x|
if x == 1
then puts "one"
elsif x == 2
then
myArray.delete x
elsif x == 3
then puts "three"
end
}

puts myArray

The output of the above is:
1
2
3
one
1
3

And my question is "why isn't it 1 2 3 one three 1 3?". What if I wanted
to make it so?

Well, you can as well do

myArray = [1, 2, 3]

puts myArray

myArray.delete_if {|x|
   if x == 1 then
     puts "one"
   elsif x == 2 then
     true
   elsif x == 3 then
     puts "three"
   end
}

puts myArray

Note, this works because puts returns nil. :slight_smile:

But I'd prefer using case

myArray.delete_if do |x|
   case x
   when 1
     puts "one"
   when 2
     true
   when 3
     puts "three"
   end
end

Cheers

  robert

···

On 24.04.2008 11:56, Peña wrote:

From: Frisco Del Rosario [mailto:frisco@appleisp.netNO] # "why isn't it 1 2 3 one three 1 3?".

a delete (of some element) on an array will really be deleted, ergo, the elements will rearrange/move to logically occupy that deleted space.

eg,
b=[1,2,3,4,5]
#=> [1, 2, 3, 4, 5]
b.delete 2
#=> 2
b
#=> [1, 3, 4, 5]

also, array#delete(obj) will delete all elements eql to obj. see below. now, if you combine these behaviours while walking the array itself, expect some surprises if you're not ready :slight_smile:

maybe if you show the index, ruby can help you, eg

a=[1,2,3,1,1,4]
#=> [1, 2, 3, 1, 1, 4]
a.each_with_index{|x,i| a.delete x if x==1; puts "#{i} -> #{x}"}
0 -> 1
1 -> 3
2 -> 4
#=> [2, 3, 4]

# What if I wanted to make it so?

there are many better ways, but i will just modify your sample,

myArray = [1, 2, 3]
puts myArray
myArray.delete 2 #here i delete 2 first
myArray.each {|x|
  if x == 1
    then puts "one"
  elsif x == 3
    then puts "three"
  end
}
puts myArray

1
2
3
one
three
1
3

kind regards -botp