Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Delete every other value in an array

123 views
Skip to first unread message

Tim Conner

unread,
May 9, 2008, 10:16:21 AM5/9/08
to
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/.

yermej

unread,
May 9, 2008, 10:33:29 AM5/9/08
to

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}

Harry Kakueki

unread,
May 9, 2008, 10:34:53 AM5/9/08
to
On Fri, May 9, 2008 at 11:16 PM, Tim Conner <crofty...@hotmail.com> 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

--
A Look into Japanese Ruby List in English
http://www.kakueki.com/ruby/list.html

Raúl Gutiérrez S.

unread,
May 9, 2008, 10:37:45 AM5/9/08
to
On Fri, 2008-05-09 at 23:16 +0900, Tim Conner 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


James Gray

unread,
May 9, 2008, 10:39:01 AM5/9/08
to
On May 9, 2008, at 9:16 AM, Tim Conner 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 Gray II

ara.t.howard

unread,
May 9, 2008, 11:08:21 AM5/9/08
to

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/
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama


ara.t.howard

unread,
May 9, 2008, 11:11:06 AM5/9/08
to

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? ;-)

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.

ara.t.howard

unread,
May 9, 2008, 11:16:38 AM5/9/08
to

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

Robert Dober

unread,
May 9, 2008, 12:27:10 PM5/9/08
to
On Fri, May 9, 2008 at 4:16 PM, Tim Conner <crofty...@hotmail.com> 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

Robert Dober

unread,
May 9, 2008, 12:28:34 PM5/9/08
to
oh I see this was part of Ara's paper on the theme ;)
BPBYT!!!

Joel VanderWerf

unread,
May 10, 2008, 12:46:29 PM5/10/08
to
Tim Conner 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"]

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

yermej

unread,
May 10, 2008, 1:00:54 PM5/10/08
to
> 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.

7stud --

unread,
May 10, 2008, 1:57:39 PM5/10/08
to
Tim Conner 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"]

David A. Black

unread,
May 10, 2008, 2:08:48 PM5/10/08
to
Hi --

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

> Tim Conner 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

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

--
Rails training from David A. Black and Ruby Power and Light:
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.rubypal.com for details and updates!

Message has been deleted

7stud --

unread,
May 10, 2008, 4:10:35 PM5/10/08
to
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.

Harry Kakueki

unread,
May 10, 2008, 7:39:54 PM5/10/08
to
>
> 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 Kakueki

unread,
May 10, 2008, 8:03:43 PM5/10/08
to
>>
>>
>
> Oops. My code has a bug.
>
> 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
>
>
Or not. :)
Which do you want?
0 new messages