我正在寻找一种方式在Ruby中选择数组中的每个第n项。例如,选择每第二个项目将改变:如何选择数组中的每个第n项?
["cat", "dog", "mouse", "tiger"]
到:
["dog", "tiger"]
是否有一个Ruby的方法,这样做,或是否有任何其他方式做到这一点?
我尝试使用类似:
[1,2,3,4].select {|x| x % 2 == 0}
# results in [2,4]
但只适用于与整数,而不是字符串数组。
我正在寻找一种方式在Ruby中选择数组中的每个第n项。例如,选择每第二个项目将改变:如何选择数组中的每个第n项?
["cat", "dog", "mouse", "tiger"]
到:
["dog", "tiger"]
是否有一个Ruby的方法,这样做,或是否有任何其他方式做到这一点?
我尝试使用类似:
[1,2,3,4].select {|x| x % 2 == 0}
# results in [2,4]
但只适用于与整数,而不是字符串数组。
您还可以使用步骤:
n = 2
a = ["cat", "dog", "mouse", "tiger"]
b = (n - 1).step(a.size - 1, n).map { |i| a[i] }
这个怎么样 -
arr = ["cat", "dog", "mouse", "tiger"]
n = 2
(0... arr.length).select{ |x| x%n == n-1 }.map { |y| arr[y] }
#=> ["dog", "tiger"]
如果你需要在其他地方,你可以添加一个方法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得到它。
您可以使用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}
另一种方式:
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))
你可以简单的使用方法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]
我喜欢Anshul和Mu的答案,并希望通过提交每个作为monkeypatch来改进和简化它们到可枚举:
穆
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]
我建议一个非常简单的方法:
animals.each_with_index.map { |_, i| i.odd? }
例如
['a','b','c','d'].select.with_index{ |_,i| i.odd? }
=> ["b", "d"]
这很好的anshul。谢谢! – sjsc 2011-01-14 08:42:41