如何选择数组中的每个第n项?

时间:2011-01-14 08:28:27

标签: ruby-on-rails ruby

我希望在Ruby中找到一种方法来选择数组中的每个第n项。例如,选择每一个项目都会改变:

["cat", "dog", "mouse", "tiger"]

成:

["dog", "tiger"]

是否有Ruby方法可以这样做,还是有其他方法可以做到这一点?

我尝试使用类似的东西:

[1,2,3,4].select {|x| x % 2 == 0}
# results in [2,4]

但这仅适用于具有整数的数组,而不适用于字符串。

10 个答案:

答案 0 :(得分:53)

您可以使用Enumerable#each_slice

["cat", "dog", "mouse", "tiger"].each_slice(2).map(&:last)
# => ["dog", "tiger"]

更新

正如评论中所提到的,last并不总是合适的,因此可以用first代替,并跳过第一个元素:

["cat", "dog", "mouse", "tiger"].drop(1).each_slice(2).map(&:first)

不幸的是,让它不那么优雅。

IMO,最优雅的是使用.select.with_index,Nakilon在评论中提出:

["cat", "dog", "mouse", "tiger"].select.with_index{|_,i| (i+1) % 2 == 0}

答案 1 :(得分:19)

您也可以使用步骤:

n = 2
a = ["cat", "dog", "mouse", "tiger"]
b = (n - 1).step(a.size - 1, n).map { |i| a[i] }

答案 2 :(得分:5)

这个怎么样 -

arr = ["cat", "dog", "mouse", "tiger"]
n = 2
(0... arr.length).select{ |x| x%n == n-1 }.map { |y| arr[y] } 
    #=> ["dog", "tiger"]

答案 3 :(得分:4)

如果您在其他地方需要,可以向Enumerable添加方法:

module Enumerable
   def select_with_index
      index = -1
      (block_given? && self.class == Range || self.class == Array)  ?  select { |x| index += 1; yield(x, index) }  :  self
   end
end

p ["cat", "dog", "mouse", "tiger"].select_with_index { |x, i| x if i % 2 != 0 }

注意:这不是我的原始代码。当我和你有同样的需求时,我从here得到了它。

答案 4 :(得分:4)

另一种方式:

xs.each_with_index.map { |x, idx| x if idx % 2 != 0 }.compact

xs.each_with_index.select { |x, idx| idx % 2 }.map(&:first)

xs.values_at(*(1...xs.length).step(2))

答案 5 :(得分:4)

您只需使用values_at方法即可。您可以在documentation中轻松找到它。

以下是一些例子:

array = ["Hello", 2, "apple", 3]
array.values_at(0,1) # pass any number of arguments you like
=> ["Hello", 2]

array.values_at(0..3) # an argument can be a range
=>["Hello", 2, "apple", 3]

我相信这会解决你的问题“狗”和“老虎”

array = ["cat", "dog", "mouse", "tiger"]
array.values_at(1,3)

和你的另一个数组

[1,2,3,4].values_at(1,3)
=> [2, 4] 

答案 6 :(得分:4)

我喜欢Anshul和Mu的答案,并想通过将每个作为monkeypatch提交给Enumerable来改进和简化它们:

<强>穆的

module Enumerable
  def every_nth(n)
    (n - 1).step(self.size - 1, n).map { |i| self[i] }
  end
end 

<强> Anshul的

module Enumerable
  def every_nth(n)
    (0... self.length).select{ |x| x%n == n-1 }.map { |y| self[y] }
  end
end 

然后它很容易使用。例如,考虑:

a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]

a.every_nth(2)
 => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24] 

a.every_nth(3)
 => [3, 6, 9, 12, 15, 18, 21, 24]

a.every_nth(5)
 => [5, 10, 15, 20, 25]

答案 7 :(得分:3)

我建议采用一种非常简单的方法:

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

e.g。

['a','b','c','d'].select.with_index{ |_,i| i.odd? }
# => ["b", "d"]

答案 8 :(得分:1)

my_array = [“猫”,“狗”,“鼠标”,“老虎”]

my_new_array = my_array.select {| x | index(x)%2 == 0}

答案 9 :(得分:0)

class Array
  def every(n)
    select {|x| index(x) % n == 0}
  end
end