

ある投稿サービスを作成しており、ランキングを作成するため、下記のような形で作成しました。

[code]

    @post_array =
    {:post=>838, 
      :count=>6,
      :rank=>1,
      :user_id=>14},
     {:post=>837,
      :count=>4,
      :rank=>2,
      :user_id=>5},
     {:post=>835.
      :count=>2,
      :rank=>3,
      :user_id=>14}
    
    post = 投稿のID
    count = 投稿についたlikeの数
    rank = 順位
    user_id = ユーザーのID
    
[/code]

このランキングでは同じユーザーの投稿は上位3投稿までしか表示させないようにしたいのですが、どのようにすればよろしいでしょうか。

よろしくお願いします。


CC BY-SA 3.0
2015-08-28T16:39:38.833
14978
2015-11-02T21:59:51.217
2015-11-02T19:36:24.807
76
5891
question
ruby
ランキングに同じユーザーの投稿を3つ以上表示させない方法


railsに頼らず、各ユーザーの上位３件ずつを抽出した作業テーブルか何かを用意してからソートすれば良いのではないでしょうか？


CC BY-SA 3.0
2015-11-02T09:09:39.157
18324
2015-11-02T09:09:39.157
8335
14978
answer


こんなメソッド（関数）を定義してみました。

[code]

    def limit_by_user(post_array, maximum)
      memo = Hash.new{|h, k| h[k] = 0 }
      post_array
        .sort_by { |post| post[:rank] }
        .select { |post|
          user_id = post[:user_id]
          (memo[user_id] += 1) <= maximum
        }
    end
    
[/code]

以下は実行結果です。

[code]

    @post_array = [
      {:post => 838, :count => 6, :rank => 1, :user_id => 14},
      {:post => 837, :count => 4, :rank => 2, :user_id => 5},
      {:post => 835, :count => 9, :rank => 3, :user_id => 14},
      {:post => 904, :count => 8, :rank => 4, :user_id => 14},
      {:post => 905, :count => 7, :rank => 5, :user_id => 14},
      {:post => 906, :count => 6, :rank => 6, :user_id => 5},
    ]
    
    puts limit_by_user(@post_array, 3)
    
    # 実行結果
    {:post=>838, :count=>6, :rank=>1, :user_id=>14}
    {:post=>837, :count=>4, :rank=>2, :user_id=>5}
    {:post=>835, :count=>9, :rank=>3, :user_id=>14}
    {:post=>904, :count=>8, :rank=>4, :user_id=>14}
    {:post=>906, :count=>6, :rank=>6, :user_id=>5}
    
[/code]

ただ、これらのデータがもしデータベースに格納されているのなら、RubyよりもSQLでフィルタリングした方が処理効率が良いかもしれません。


CC BY-SA 3.0
2015-11-02T21:59:51.217
18339
2015-11-02T21:59:51.217
85
14978
answer