排名(前3位)最多出现在N个列表中的用户?

时间:2017-10-31 16:54:33

标签: c# linq xamarin

所以,我有一个N图像列表和每个图像我有一个相互作用的列表。我需要对在图像(列表)中进行最多交互的用户进行排名。 在堆栈中搜索我看到了与LINQ相交的一些东西,但不是我需要的东西。

我从开发开始......所以,我不太了解LINQ

2 个答案:

答案 0 :(得分:1)

尝试这样的事情,linq将完成这项工作

 public class User
    {
        public User(int id)
        {
            Id = id;
        }
        public int Id { get; set; }
    }

    public class Image
    {
        public int Id { get; set; }
        public List<User> Users { get; set; }
    }
.......

     public List<Tuple<int, int>> OrderByUser(IList<Image> cursos)
            {
                 var data = cursos.SelectMany(x => x.Users
                .Select(p => new { image = x, user = p }))
                .GroupBy(x => x.user.Id)
                .Select(x => new { userId = x.Key, total = x.Count() })
                .OrderByDescending(x => x.total)
                .Take(3);
            data = data.OrderByDescending(x => x.total);
            return data.Select(x=> new Tuple<int, int>(x.userId, x.total)).ToList();
            }

答案 1 :(得分:1)

如果您的图片对象的属性Users是与其互动的用户的List,那么您可以在图片列表中使用SelectMany来获取每个图像的用户并将它们展平为一个列表:

listOfImages.SelectMany(image => image.Users)

这不会删除重复项,因此每个用户每次与图片交互时都会显示一次。然后,您可以使用GroupBy对“重复”进行分组。用户分组;每个组的大小将是用户在展平列表中出现的次数:

listOfImages.SelectMany(image => image.Users)
            .GroupBy(user => user)

然后,由于您需要前三名,请使用OrderByDescending按照他们出现的次数对其进行排名,然后使用Take(3)进行前三名。然后,您需要使用Select返回用户列表,因为GroupBy会返回通用类型IGroupingFirstOrDefault()会返回每个组中的第一个项目(即用户),如果该组为空,则返回null

listOfImages.SelectMany(image => image.Users)
            .GroupBy(user => user)
            .OrderByDescending(group => group.Count())
            .Take(3)
            .Select(group => group.FirstOrDefault())

这应该有希望实现你想要的。我建议您阅读LINQ,以便了解其所有方法的工作原理 - 一旦您知道如何使用它,它就非常有用。稍微玩一下,这样你就能感受到它 - 像OrderByTake这样的方法非常明显,其他像SelectMany这样的方法并不那么明显。