0

我想编制一份推荐朋友的名单。

我在想的是这样的(这是半伪(sudo)代码!):

recommended_friends = []
friends.each do |friend|
   while recommeded_friends.length < 10
      friend.friends.each do |friend|
         if friend.in?(recommeded_friends)
             recommeded_friends[friend][counter] += 1
         else
             recommeded_friends << [friend, 0]
         end
      end
    end
end

但这显然行不通。你们将如何处理这个问题?

感谢您的任何建议。

表格(一些被缩短):

Users:
id | name 

Friendships
id | user_1_id | user_2_id | requested_at | accepted_at | declined_at |

user1 和 user2 之间的友谊在数据库中只发生一次。

4

3 回答 3

0

更新。尝试这样的事情,它应该工作:

recommended_friends = {}
friends.each do |friend|
   if recommeded_friends.length < 10
      friend.friends.each do |other_friend|
         if other_friend != this_user          # exclude myself 
           recommeded_friends[other_friend] =
             (recommeded_friends[other_friend] | 0) + 1
         end
      end
   end
end
recommendend_friends.sort_by{|key, value| value}.reverse
top_ten = recommended_friends.first(10).map{|a| a[0]}

SQL 版本:

Users.find_by_sql([
  "SELECT u.*
   FROM 
   (SELECT f2.id, f2.user_1_id u_1_id, f2.user_2_id u_2_id, (count(f1.id)) cnt
      FROM friendships f1 
      JOIN friendships f2 ON f1.user_1_id = f2.user_1_id
                          OR f1.user_2_id = f2.user_1_id
                          OR f1.user_2_id = f2.user_2_id
                          OR f1.user_1_id = f2.user_2_id
      WHERE (f1.user_1_id = ? OR f1.user_2_id = ?)
        AND (f2.user_1_id <> ? AND f2.user_2_id <> ?)
      GROUP BY f2.id, f2.user_1_id, f.user_2_id
      HAVING count(f2.id) = 1
      ORDER BY cnt DESC) fs
   JOIN friendships ff ON ff.user_1_id = fs.u_1_id
                       OR ff.user_2_id = fs.u_1_id
                       OR ff.user_2_id = fs.u_2_id
                       OR ff.user_1_id = fs.u_2_id
   JOIN users u ON 
     CASE WHEN (ff.user_1_id = fs.u_1_id OR ff.user_2_id = fs.u_1_id) 
                THEN fs.u_2_id ELSE fs.u_1_id END = u.id ", 
 user.id, user.id, user.id, user.id]).first(10)

理论上应该可以的,试试看。

于 2012-07-05T10:40:55.590 回答
0

recommeded_friends 将始终保持为空数组。你不能这样做:recommeded_friends < 10

试试这个:recommeded_friends.length < 10

于 2012-07-05T10:41:54.670 回答
0

我能想到的最简单的方法:

 recommended_friends = friend.friends.sort do |a,b|
   a <=> b # insert your ranking algorithm here
 end.take 10
于 2012-07-06T07:21:48.097 回答