Odd (or even) entries in a Ruby Array
RubyRuby Problem Overview
Is there a quick way to get every other entry in an Array in Ruby? Either the odd or even entries values with 0 included in the odd. I'd like to be able to use it like this:
array1 += array2.odd_values
or
puts array2.odd_values.join("-")
for example
Update
This give exactly what I'm after but I'm sure there is a shorter version.
array1.each_with_index do |item,index|
if (index %2 ==0) then
array2.push(item)
end
end
Ruby Solutions
Solution 1 - Ruby
a = ('a'..'z').to_a
a.values_at(* a.each_index.select {|i| i.even?})
# => ["a", "c", "e", "g", "i", "k", "m", "o", "q", "s", "u", "w", "y"]
a.values_at(* a.each_index.select {|i| i.odd?})
# => ["b", "d", "f", "h", "j", "l", "n", "p", "r", "t", "v", "x", "z"]
So, as requested
class Array
def odd_values
self.values_at(* self.each_index.select {|i| i.odd?})
end
def even_values
self.values_at(* self.each_index.select {|i| i.even?})
end
end
Solution 2 - Ruby
...
arr = ["0", "1", "2", "3"]
arr.select.each_with_index { |_, i| i.odd? }
arr.select.each_with_index { |_, i| i.even? }
As floum pointed out, in Ruby 2.2 you can simply do:
arr.select.with_index { |_, i| i.odd? }
Solution 3 - Ruby
left,right = a.partition.each_with_index{ |el, i| i.even? }
Solution 4 - Ruby
You can just use this:
(1..6).partition { |v| v.even? } #=> [[2, 4, 6], [1, 3, 5]]
From Ruby docs: Ruby Docs Reference
Solution 5 - Ruby
Some crazy way using facets:
require 'facets'
array = [1,2,3,4,5]
odd = array.to_h.keys # 1,3,5
even = array.to_h.values.compact # 2,4
Solution 6 - Ruby
This will probably never be read, but...
Simple and clean:
array2.map{ |n| n if n % 2 == 0 }.compact # evens
array2.map{ |n| n if n % 2 == 1 }.compact # odds
Just found an even more terse way (gotta love Ruby):
array2.find_all{ |n| n % 2 == 0 } # evens
array2.reject { |n| n % 2 == 0 } # odds
Solution 7 - Ruby
dst = []
array.each_slice(2) { |x| dst.push(x[1]) }
should give you an array of the odd indices.
Replace x[1]
with x[0]
for the even entries.
Solution 8 - Ruby
odds = array.each_slice(2).map(&:first)
evens = array.each_slice(2).map(&:last)
Solution 9 - Ruby
For the record:
a = [1,2,3,4,5,6]
h = Hash[*a]
evens = h.keys
odds = h.values
I'm using the 'splat' operator of Array to get comma separated values and pass that to Hash which accepts arguments as alternating keys/values.
Solution 10 - Ruby
Another way to think about it (adds array2 evens to array1):
array1 << array2.values_at(*Array.new(array2.size/2){|i| i*2})
Solution 11 - Ruby
This seems like the most Rubyish solution, combining the best of JacobM and glenn jackman's approaches.
module ::Enumerable
def select_with_index
index = -1
select { |x| yield(x, (index += 1)) }
end
def odds
select_with_index {|x,i| i.odd?}
end
def evens
select_with_index {|x,i| i.even?}
end
end
Solution 12 - Ruby
With a blank array A
, and a full array H
, something like this should work:
H.size.times do |i|
if i % 2 == 1
A[i/2] = H[i]
end
end
Solution 13 - Ruby
This might work for you, or then again, not :-)
irb(main):050:0> all = [1,2,3,4,5,6,7,8,9]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):051:0> evens = []
=> []
irb(main):052:0> all.each_index do |i| if (i.even?): evens.push(a[i]) end end
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):053:0> evens
=> [1, 3, 5, 7, 9]
Solution 14 - Ruby
Here's a code snippet that's intended to add a select_with_index method to Enumerable, which would allow you to do
array.select_with_index{|item, i| item if i % 2 == 0}
for evens
array.select_with_index{|item, i| item if i % 2 == 1}
for odds
Solution 15 - Ruby
My take on the problem, defining simple Array extensions:
class Array
def odd_values
(0...length / 2).collect { |i| self[i*2 + 1] }
end
def even_values
(0...(length + 1) / 2).collect { |i| self[i*2] }
end
end
puts [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ].odd_values.inspect
# => [1, 3, 5, 7, 9]
puts [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ].even_values.inspect
# => [0, 2, 4, 6, 8]
puts [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ].even_values.inspect
# => [0, 2, 4, 6, 8]
puts [ ].even_values.inspect
# => []
Solution 16 - Ruby
a = [0,1,2,3,4,5,6,7,8,9]
(1...a.size).step(2).collect { |i| a[i] }
=> [1, 3, 5, 7, 9]
(2...a.size).step(2).collect { |i| a[i] }
=> [2, 4, 6, 8]
Of course, considering 0 an odd index creates a little hackery, right? Since you will have adjacent entries that are in effect odd indicies. To compensate for that you can just add the zeroth entry to the result of the first collect. Consider:
[a[0]] + (1...a.size).step(2).collect { |i| a[i] }
=> [0, 1, 3, 5, 7, 9]
You could always compact this further and do something like:
a.values_at(*(1...a.size).step(2))
=> [1, 3, 5, 7, 9]
a.values_at(*(2...a.size).step(2))
=> [2, 4, 6, 8]
The same hack is available to handle the zeroth entry.
Solution 17 - Ruby
evens = (1..10).each_with_object([]) {|i, a| a << i*2 }
#=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Solution 18 - Ruby
a = [1,2,3,4,5]
a.in_groups_of(2).map(&:first) => odds
a.in_groups_of(2).map(&:last) => evens
Solution 19 - Ruby
module Enumerable
def odd_values
r = []
self.each_index {|x| r << self[x] if x%2==0}
r
end
end
p ["a", "b" ,"c" ,"d" ,"e"].odd_values #returns ["a","c","e"]
p ["a", "b" ,"c" ,"d" ,"e"].odd_values.join("-") #returns "a-c-e"
I just reused an approach i used for another question on arrays. :D
Solution 20 - Ruby
Don't forget good old friend Array.inject
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a.inject([]){|result, item| result << item if item %2 == 1; result}
Should give you odd items.
Solution 21 - Ruby
I suggest the use of Enumerable#Inject function
array = (1..30)
array.inject({even: [], odd: []}){|memo, element| memo[element.even? ? :even : :odd] << element; memo}
Solution 22 - Ruby
Slightly left field, but I recently needed something I could pass to select
as a proc:
def alternator
gen = [true,false].cycle
proc { gen.next }
end
self.filter = alternator
# ... elsewhere/much later ...
input = 'a'..'z'
input.select(&filter)
Some may suggest this could even be a case for Enumerator.new
or even a Fiber, which would both technically be simpler constructs, but I think at the expense of clarity.