Ruby/Rails:从数组中获取元素,其中索引可被x整除
我怎样才能实现这个?我认为我的解决方案很脏,我想做得更好。我认为在 Ruby 中有一个简单的方法可以做到这一点,但我不记得了。我想将它与 Rails 一起使用,所以如果 Rails 提供类似的东西也可以。用法应该是这样的:
fruits = ['banana', 'strawberry', 'kiwi', 'orange', 'grapefruit', 'lemon', 'melon']
# odd_fruits should contain all elements with odd indices (index % 2 == 0)
odd_fruits = array_mod(fruits, :mod => 2, :offset => 0)
# even_fruits should contain all elements with even indices (index % 2 == 1)
even_fruits = array_mod(fruits, :mod => 2, :offset => 1)
puts odd_fruits
banana
kiwi
grapefruit
melon
puts even_fruits
strawberry
orange
lemon
***** 编辑 *******
对于那些想知道的人,这就是我最终所做的:
在 Rails 项目中,我创建了一个新文件 config/ initializers/columnize.rb 看起来像这样:
class Array
def columnize args = { :columns => 1, :offset => 0 }
column = []
self.each_index do |i|
column << self[i] if i % args[:columns] == args[:offset]
end
column
end
end
Rails 加载后立即自动加载这些文件。我还使用了 Railsy 方式为方法提供参数,因为我认为这有助于提高代码的可读性,而且我是一个良好的可读代码迷恋者:)我扩展了核心类“Array”,现在我可以对项目中的每个数组执行以下操作:
>> arr = [1,2,3,4,5,6,7,8]
=> [1, 2, 3, 4, 5, 6, 7, 8]
>> arr.columnize :columns => 2, :offset => 0
=> [1, 3, 5, 7]
>> arr.columnize :columns => 2, :offset => 1
=> [2, 4, 6, 8]
>> arr.columnize :columns => 3, :offset => 0
=> [1, 4, 7]
>> arr.columnize :columns => 3, :offset => 1
=> [2, 5, 8]
>> arr.columnize :columns => 3, :offset => 2
=> [3, 6]
我现在将使用它在视图中的不同列中显示数据库中的条目。我喜欢它的是,我不必调用任何紧凑的方法或东西,因为当你将 nil 对象传递给视图时,rails 会抱怨。现在它就可以了。我也想过让 JS 为我做这一切,但我更喜欢这种方式,使用 960 Grid 系统 (http:// /960.gs)
How could I implement this? I think my solution is very dirty, and I would like to do it better. I think there is an easy way to do this in Ruby, but I can't remember. I want to use it with Rails, so if Rails provides something similar that's ok, too. usage should be like this:
fruits = ['banana', 'strawberry', 'kiwi', 'orange', 'grapefruit', 'lemon', 'melon']
# odd_fruits should contain all elements with odd indices (index % 2 == 0)
odd_fruits = array_mod(fruits, :mod => 2, :offset => 0)
# even_fruits should contain all elements with even indices (index % 2 == 1)
even_fruits = array_mod(fruits, :mod => 2, :offset => 1)
puts odd_fruits
banana
kiwi
grapefruit
melon
puts even_fruits
strawberry
orange
lemon
******* EDIT *******
for those wo want to know, that is what i finally did:
in a rails project, i created a new file config/initializers/columnize.rb
which looks like this:
class Array
def columnize args = { :columns => 1, :offset => 0 }
column = []
self.each_index do |i|
column << self[i] if i % args[:columns] == args[:offset]
end
column
end
end
Rails automatically loads these files immediately after Rails has been loaded. I also used the railsy way of supplying arguments to a method, because i think that serves the purpose of better readable code, and i'm a good-readable-code-fetishist :) I extended the core class "Array", and now i can do things like the following with every array in my project:
>> arr = [1,2,3,4,5,6,7,8]
=> [1, 2, 3, 4, 5, 6, 7, 8]
>> arr.columnize :columns => 2, :offset => 0
=> [1, 3, 5, 7]
>> arr.columnize :columns => 2, :offset => 1
=> [2, 4, 6, 8]
>> arr.columnize :columns => 3, :offset => 0
=> [1, 4, 7]
>> arr.columnize :columns => 3, :offset => 1
=> [2, 5, 8]
>> arr.columnize :columns => 3, :offset => 2
=> [3, 6]
I will now use it to display entries from the database in different columns in my views. What i like about it, is that i don't have to call any compact methods or stuff, because rails complains when you pass a nil object to a view. now it just works. I also thought about letting JS do all that for me, but i like it better this way, working with the 960 Grid system (http://960.gs)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
用法:
Usage:
我能想到的最简单的方法是这样的:
如果数组可以为您查找索引,您就不需要搞乱
select_with_index
。我认为此方法的缺点是,如果“fruits”中有多个具有相同值的条目(index
方法仅返回第一个匹配条目的索引)。The simplest method I can think of is this:
You don't need to mess with
select_with_index
if the array can look up indices for you. I suppose the drawback to this method is if you have multiple entries in 'fruits' with the same value (theindex
method returns the index of the first matching entry only).您想要的是:
不幸的是
Enumerable#select_with_index
并不作为标准存在,但有几个人用这样的方法扩展了Enumerable
。http://snippets.dzone.com/posts/show/3746
http://webget.com/gems/webget_ruby_ramp/doc/Enumerable.html# M000058
What you want is:
Unfortunately
Enumerable#select_with_index
does not exist as standard, but several people have extendedEnumerable
with such a method.http://snippets.dzone.com/posts/show/3746
http://webget.com/gems/webget_ruby_ramp/doc/Enumerable.html#M000058
仅使用核心功能的解决方案:
Solution using just core capabilities:
Rails 为 Array 提供了 ActiveSupport 扩展,该扩展提供了“in_groups_of”方法。这就是我通常用于此类事情的方法。它允许你这样做:
拉出偶数水果(记得压缩以在最后拉出零):
拉出奇数水果:
要获得每三个水果,您可以使用:
Rails provides an ActiveSupport extension to Array that provides an "in_groups_of" method. That's what I usually use for things like this. It allows you to do this:
to pull the even fruits (remember to compact to pull off nils at the end):
to pull the odd fruits:
to get every third fruit, you could use:
功能方式
functional way
这是使用 #enum_for 的解决方案,它允许您指定使用“就地”#each 的方法:
Here's a solution using #enum_for, which allows you to specify a method to use "in place" of #each: