我有五个类别,每个类别约五个帖子。 E.g。
=> category_a.posts
=> #<Post id:01>, #<Post id:02>, #<Post id:03> etc
=> category_b.posts
=> #<Post id:10>, #<Post id:11>, #<Post id:12> etc
=> category_c.posts
=> #<Post id:20>, #<Post id:21>, #<Post id:22> etc
我喜欢一系列儿童,他们交错(尽可能均匀),即
#<Post id:01>, #<Post id:10>, #<Post id:20>, #<Post id:02>, #<Post id:11> etc
我怎么能做到这一点?
答案 0 :(得分:2)
Dave Schweisguth的回答很好,可能会让您知道解决问题需要了解的内容。但是,该解决方案不允许您选择项目交错的顺序。这是一个有希望的更通用的解决方案:
def full_zip(*args)
max_len = args.map(&:length).max
([nil] * max_len).zip(*args).flatten.compact
end
然后会像full_zip(category_a.posts, category_b.posts, category_c.posts)
或full_zip(*[cat_a, cat_z].map(&:posts))
一样使用它。按照您希望的顺序使用类别。
编辑:这个问题的一个问题是,如果原始列表中有你想保留的nils。
答案 1 :(得分:1)
它只有五个查询和大约15个模型,所以在内存中这样做很好:
posts =
[category_a, category_b, category_c, category_d, category_e].
map(&:posts)
sort_by(&:length)
posts.first.zip(*posts[1..-1]).flatten.compact
首先放置最长的数组会阻止zip
在其参数中从数组中删除元素,这些元素的长度超过它所调用的数组。 compact
会删除nil
创建的zip
,如果其参数中的数组长于它所调用的数组。