Delete every other value in an array

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

thanks

On Fri, May 9, 2008 at 11:16 PM, Tim C. [email protected]
wrote:

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

thanks

Here is one way.

arr = %w[a b c d e f g h i j k]
p arr.select{|x| arr.index(x) % 2 == 0}

Harry

On Fri, 2008-05-09 at 23:16 +0900, Tim C. wrote:

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

v = %w(a b c d e f g h i j k)

cnt = 0
v.each { |i|
v.delete(0) if cnt % 2 != 0
cnt += 1
}

rgs

On May 9, 9:16 am, Tim C. [email protected] wrote:

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

thanks

Posted viahttp://www.ruby-forum.com/.

This will work, but I’m not sure if it’s the best way.

a = %w(a b c d e f g h i j k)
1.upto(a.size) {|i| a.delete_at i}

On May 9, 2008, at 9:16 AM, Tim C. wrote:

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

ary = (“a”…“k”).to_a
=> [“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]

require “enumerator”
=> true

ary.enum_slice(2).map { |pair| pair.first }
=> [“a”, “c”, “e”, “g”, “i”, “k”]

Hope that helps.

James Edward G. II

On May 9, 2008, at 8:35 AM, yermej wrote:

a = %w(a b c d e f g h i j k)
1.upto(a.size) {|i| a.delete_at i}

it does, but accidentally:

cfp:~ > cat a.rb

a = %w(a b c d e f g h i j k)

1.upto(a.size) do |i|
puts ‘—’
p :i => i
p :before => a
a.delete_at i
p :after => a
end

cfp:~ > ruby a.rb

{:i=>1}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>2}
{:before=>[“a”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “c”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>3}
{:before=>[“a”, “c”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “c”, “e”, “g”, “h”, “i”, “j”, “k”]}

{:i=>4}
{:before=>[“a”, “c”, “e”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “c”, “e”, “g”, “i”, “j”, “k”]}

{:i=>5}
{:before=>[“a”, “c”, “e”, “g”, “i”, “j”, “k”]}
{:after=>[“a”, “c”, “e”, “g”, “i”, “k”]}

{:i=>6}
{:before=>[“a”, “c”, “e”, “g”, “i”, “k”]}
{:after=>[“a”, “c”, “e”, “g”, “i”, “k”]}

{:i=>7}
{:before=>[“a”, “c”, “e”, “g”, “i”, “k”]}
{:after=>[“a”, “c”, “e”, “g”, “i”, “k”]}

{:i=>8}
{:before=>[“a”, “c”, “e”, “g”, “i”, “k”]}
{:after=>[“a”, “c”, “e”, “g”, “i”, “k”]}

{:i=>9}
{:before=>[“a”, “c”, “e”, “g”, “i”, “k”]}
{:after=>[“a”, “c”, “e”, “g”, “i”, “k”]}

{:i=>10}
{:before=>[“a”, “c”, “e”, “g”, “i”, “k”]}
{:after=>[“a”, “c”, “e”, “g”, “i”, “k”]}

{:i=>11}
{:before=>[“a”, “c”, “e”, “g”, “i”, “k”]}
{:after=>[“a”, “c”, “e”, “g”, “i”, “k”]}

look carefully at what’s happening for i >= 6.

the indexes map only by accident since each delete modifies the
mapping in the array (size reduced by one after each delete)

a @ http://codeforpeople.com/

On May 9, 2008, at 8:37 AM, Raúl Gutiérrez S. wrote:

v = %w(a b c d e f g h i j k)

cnt = 0
v.each { |i|
v.delete(0) if cnt % 2 != 0
cnt += 1
}

are you sure? :wink:

cfp:~ > cat a.rb
v = %w(a b c d e f g h i j k)

cnt = 0
v.each do |i|
puts ‘—’
p :i => i
p :before => v
v.delete(0) if cnt % 2 != 0
cnt += 1
p :after => v
end

puts ‘===’
p v

cfp:~ > ruby a.rb

{:i=>“a”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“b”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“c”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“d”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“e”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“f”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“g”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“h”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“i”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“j”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

{:i=>“k”}
{:before=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}
{:after=>[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]}

[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”]

you cannot simultaneously iterate and delete from and enumerable in
ruby.

a @ http://codeforpeople.com/

On Fri, May 9, 2008 at 4:16 PM, Tim C. [email protected]
wrote:

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

what about #values_at
x.values_at( *(0…x.size).map{|i| (i%2).zero? && i || nil}.compact) )

too bad compact does not do what I want ;).

HTH
Robert

thanks

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


http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

oh I see this was part of Ara’s paper on the theme :wink:
BPBYT!!!

On May 9, 2008, at 8:16 AM, Tim C. wrote:

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

thanks

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

cfp:~ > cat a.rb

the list

a = %w(a b c d e f g h i j k)

build your index up all at once

evens = Array.new(a.size / 2){|i| i * 2}
ods = Array.new(a.size / 2){|i| i * 2 + 1}

apply it

p a.values_at(*evens)
p a.values_at(*ods)

apply it destructively

a.replace a.values_at(*evens)
p a

cfp:~ > ruby a.rb
[“a”, “c”, “e”, “g”, “i”]
[“b”, “d”, “f”, “h”, “j”]
[“a”, “c”, “e”, “g”, “i”]

a @ http://codeforpeople.com/

Tim C. wrote:

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

thanks

This solution is less elegant and rubylike than some of the others, but
at least it is fairly portable…

a = %w(a b c d e f g h i j k)

n = (a.size/2.0).ceil
n.times do |i|
a[i] = a[2*i]
end
a.slice!(n…-1)

p a # ==> [“a”, “c”, “e”, “g”, “i”, “k”]

Tim C. wrote:

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

thanks

letters = (“a”…“z”).to_a
last_index = letters.length - 1

results = []

0.step(last_index, 2) do |i|
results << letters[i]
end

letters = results
p letters

–output:–
[“a”, “c”, “e”, “g”, “i”, “k”, “m”, “o”, “q”, “s”, “u”, “w”, “y”]

Hi –

On Sun, 11 May 2008, 7stud – wrote:

letters = (“a”…“z”).to_a
last_index = letters.length - 1

results = []

0.step(last_index, 2) do |i|
results << letters[i]
end

letters = results
p letters

In Ruby 1.9 you can do:

letters.values_at(*0.step(letters.size-1,2))

using the enumerator returned from step called without a block.

David

Tim C. wrote:

What is the best way to delete every other value in a ruby array?
e.g.
%w(a b c d e f g h i j k)

becomes => [a c e g i k]

thanks

irb(main):001:0> a = (“a”…“z”).to_a
=>
[“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”, “l”, “m”, “n”,
“o”, “p”, “q”, “r”, “s”, “t”, “u”, “v”, “w”, “x”, “y”, “z”]
irb(main):002:0> for i in 1…a.size/2
irb(main):003:1> a.delete_at(i)
irb(main):004:1> end
=> 1…13
irb(main):005:0> a
=> [“a”, “c”, “e”, “g”, “i”, “k”, “m”, “o”, “q”, “s”, “u”, “w”, “y”]
irb(main):006:0>

On May 9, 10:08 am, “ara.t.howard” [email protected] wrote:

{:i=>1}

{:after=>[“a”, “c”, “e”, “g”, “i”, “k”]}
{:before=>[“a”, “c”, “e”, “g”, “i”, “k”]}
look carefully at what’s happening for i >= 6.

the indexes map only by accident since each delete modifies the
mapping in the array (size reduced by one after each delete)

a @http://codeforpeople.com/

we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama

Oops…I really should have noticed that. In a hurry, I guess. I’ll
vote for:

a = %w(a b c d e f g h i j k)
1.upto(a.size/2) {|i| a.delete_at i}

as the accidentally obfuscated solution of the day.

David A. Black wrote:

In Ruby 1.9 you can do:

letters.values_at(*0.step(letters.size-1,2))

using the enumerator returned from step called without a block.

Thanks, but I prefer to break with Ruby tradition and not write one
liners that could win obfuscation contests.

(0…arr.length).step(2) {|x| res << arr[x]}
p res #> [“a”, “c”, “b”, “g”, “i”, “k”, “m”]

Harry

Or not. :slight_smile:
Which do you want?

Harry

Here is one way.

arr = %w[a b c d e f g h i j k]
p arr.select{|x| arr.index(x) % 2 == 0}

Harry

Oops. My code has a bug. It can fall down when there are duplicates.
Try this.

arr = %w[a b c d b f g h i j k l m]

p arr.select{|x| arr.index(x) % 2 == 0}#> [“a”, “c”, “g”, “i”, “k”, “m”]

res = []
(0…arr.length).step(2) {|x| res << arr[x]}
p res #> [“a”, “c”, “b”, “g”, “i”, “k”, “m”]

Harry