Delete every other value in an array

T

Tim Conner

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
 
Y

yermej

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 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}
 
H

Harry Kakueki

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
 
R

Raúl Gutiérrez S.

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
 
J

James Gray

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
 
A

ara.t.howard

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/
 
A

ara.t.howard

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

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

are you sure? ;-)

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

cnt =3D 0
v.each do |i|
puts '---'
p :i =3D> i
p :before =3D> v
v.delete(0) if cnt % 2 !=3D 0
cnt +=3D 1
p :after =3D> v
end


puts '=3D=3D=3D'
p v




cfp:~ > ruby a.rb
---
{:i=3D>"a"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"b"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"c"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"d"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"e"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"f"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"g"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"h"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"i"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"j"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
---
{:i=3D>"k"}
{:before=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
{:after=3D>["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]}
=3D=3D=3D
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]



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



a @ http://codeforpeople.com/
 
A

ara.t.howard

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



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/
 
R

Robert Dober

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
 
J

Joel VanderWerf

Tim said:
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 = a[2*i]
end
a.slice!(n..-1)

p a # ==> ["a", "c", "e", "g", "i", "k"]
 
Y

yermej

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/

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.
 
7

7stud --

Tim said:
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
end

letters = results
p letters

--output:--
["a", "c", "e", "g", "i", "k", "m", "o", "q", "s", "u", "w", "y"]
 
D

David A. Black

Hi --

Tim said:
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
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!
 
7

7stud --

David said:
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.
 
H

Harry Kakueki

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
 
H

Harry Kakueki

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?

Harry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,204
Messages
2,571,065
Members
47,672
Latest member
svaraho

Latest Threads

Top