Ruby数组中的奇数(或偶数)条目

时间:2009-10-23 15:15:11

标签: ruby

有没有快速的方法来获取Ruby中的数组中的所有其他条目?奇数或偶数条目值包含在奇数中。我希望能够像这样使用它:

array1 += array2.odd_values

puts array2.odd_values.join("-")

例如

更新

这正是我所追求的,但我确信有一个较短的版本。

array1.each_with_index do |item,index| 
  if (index %2 ==0) then 
    array2.push(item) 
  end
end

22 个答案:

答案 0 :(得分:82)

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

所以,按照要求

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

答案 1 :(得分:66)

...

arr = ["0", "1", "2", "3"]
arr.select.each_with_index { |_, i| i.odd? }
arr.select.each_with_index { |_, i| i.even? }

正如floum所指出的,在Ruby 2.2中你可以做到:

arr.select.with_index { |_, i| i.odd? }

答案 2 :(得分:19)

你可以使用它:

(1..6).partition { |v| v.even? }  #=> [[2, 4, 6], [1, 3, 5]]

来自Ruby docs:Ruby Docs Reference

答案 3 :(得分:15)

left,right = a.partition.each_with_index{ |el, i| i.even? }

答案 4 :(得分:9)

使用方面的一些疯狂方式:

require 'facets'
array = [1,2,3,4,5]
odd = array.to_h.keys # 1,3,5
even = array.to_h.values.compact # 2,4

答案 5 :(得分:8)

这可能永远不会被阅读,但是......

简单干净:

array2.map{ |n| n if n % 2 == 0 }.compact # evens

array2.map{ |n| n if n % 2 == 1 }.compact # odds

刚刚找到一种更简洁的方式(得爱Ruby):

array2.find_all{ |n| n % 2 == 0 } # evens

array2.reject  { |n| n % 2 == 0 } # odds

答案 6 :(得分:5)

dst = []
array.each_slice(2) { |x| dst.push(x[1]) }

应该给你一个奇数索引的数组。

x[1]替换为偶数条目的x[0]

答案 7 :(得分:4)

记录:

a = [1,2,3,4,5,6]
h = Hash[*a]
evens = h.keys
odds = h.values

我正在使用' splat' Array的运算符以获取逗号分隔值并将其传递给Hash,Hash接受参数作为交替键/值。

答案 8 :(得分:4)

odds = array.each_slice(2).map(&:first)
evens = array.each_slice(2).map(&:last)

答案 9 :(得分:2)

考虑它的另一种方法(将array2 evens添加到array1):

array1 << array2.values_at(*Array.new(array2.size/2){|i| i*2})

答案 10 :(得分:2)

这似乎是最Rubyish的解决方案,结合了JacobM和glenn jackman的最佳方法。

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

答案 11 :(得分:1)

evens = (1..10).each_with_object([]) {|i, a| a << i*2 }
#=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

答案 12 :(得分:1)

a = [1,2,3,4,5]
a.in_groups_of(2).map(&:first) => odds
a.in_groups_of(2).map(&:last) => evens

答案 13 :(得分:1)

使用空白数组A和完整数组H,这样的事情应该有效:

H.size.times do |i|
  if i % 2 == 1
    A[i/2] = H[i]
  end
end

答案 14 :(得分:1)

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]

当然,考虑到0,一个奇怪的索引会产生一些小问题,对吧?因为您将有相邻的条目实际上是奇数指标。为了弥补这一点,您只需将第0个条目添加到第一个收集的结果中即可。考虑:

[a[0]] + (1...a.size).step(2).collect { |i| a[i] }
=> [0, 1, 3, 5, 7, 9]

你总是可以进一步压缩这个并做类似的事情:

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]

同样的hack可用于处理第0个条目。

答案 15 :(得分:1)

我对这个问题的看法,定义了简单的数组扩展:

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
# => []

答案 16 :(得分:1)

这是一个code snippet,旨在将select_with_index方法添加到Enumerable中,这样就可以了

array.select_with_index{|item, i| item if i % 2 == 0}为evens

array.select_with_index{|item, i| item if i % 2 == 1}赔率

答案 17 :(得分:1)

这可能对你有用,或者说再次,不是: - )

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]

答案 18 :(得分:0)

不要忘记好老朋友Array.inject

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a.inject([]){|result, item| result << item if item %2 == 1; result}

应该给你奇怪的物品。

答案 19 :(得分:0)

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"

我只是重复使用了一种用于数组上另一个问题的方法。 :d

答案 20 :(得分:0)

我建议使用Enumerable #Inject函数

array = (1..30)    
array.inject({even: [], odd: []}){|memo, element| memo[element.even? ? :even : :odd] << element; memo}

答案 21 :(得分:0)

字段稍微偏左,但我最近需要一些可以作为过程传递给select的东西:

def alternator
  gen = [true,false].cycle
  proc { gen.next }
end

self.filter = alternator

# ... elsewhere/much later ...
input = 'a'..'z'
input.select(&filter)

有人可能甚至认为Enumerator.new甚至是Fiber都是这种情况,从技术上讲,这两者都是较简单的构造,但我认为这样做会牺牲清晰度。