2016-05-17 6 views
1

私はそれぞれ約5つの投稿で5つのカテゴリを持っています。例えば。複数のActiveRecord関連付けクエリをインターリーブする方法は?

=> 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 

どのように私はこれを達成するだろうか?

答えて

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つの問題があります。

+0

私の解決策の次の進化は、すべての配列を 'nil'で与えられた長さに塗りつぶして並べ替えを保存して順序を保持することですが、これはより良い方法です。小さな提案: 'max_len' =' args.max_by&:length'そして '[nil] * max_len'の代わりに' Array [max_len] 'を使うだけです。 –

+0

'Array [max_len]'はもっと意味的には正解でしょうが、 'Array.new(max_len)'や 'Array.new(max_len、nil)'と思っています。乗算のトリックは、新しい配列(古いものから、または平坦なものを使わなくても派手な形状から)を作るときには、もっと簡単/一般的かもしれないので、いいです。 – user2251284

+0

'max_by'トリックもいいですが、' foo.max_by(&:length).length'でなければなりません。 – user2251284

1

メモリにそれを行うために大丈夫だと思うので、それは、唯一の5つのクエリと周りの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は、zipによって作成されたnilを削除します。引数の配列が呼び出された配列より長い場合

+0

私の理解では、カテゴリaからカテゴリーaまでの上位のインデックスより高い上位のインデックスを持つカテゴリbからeのアイテムアイテムは無視されます。詳細はこちらをご覧ください:http://apidock.com/ruby/Array/zip。 – user2251284

+0

もう一つのことは、わかりませんが、これで、category_aの投稿は投稿のリストとインターリーブされます。これは "[1,1,1] .zip([[2,2,2]、[3,3,3]、[4,4,4]])=> [[1、 1,2,2]]、[1、[3,3,3]]、[1、[4,4,4]]]である。私は、あなたがzip関数に送る配列の前にある "*"記号がその配列を分解して解決すると思います。代わりに、私はあなたが "マップ(&:ポスト)"(私はあなたがそこに余分なコロンが必要だろうと思う)の後に平らにすることができると思います。 – user2251284

+0

編集して以来、私の上記2つのコメントはもはや問題ではありません。しかし、今考慮すべきことの1つは、プログラムのユーザーが実際に投稿がどのような順番で圧縮されるのかを実際は制御できないことです。また、nilsを維持したい場合は、私と同じ問題が発生します。それが誰にとっても重要であれば、コメントを残しておいてください。 – user2251284

関連する問題