所以,我有一个N图像列表和每个图像我有一个相互作用的列表。我需要对在图像(列表)中进行最多交互的用户进行排名。 在堆栈中搜索我看到了与LINQ相交的一些东西,但不是我需要的东西。
我从开发开始......所以,我不太了解LINQ
答案 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
会返回通用类型IGrouping
。 FirstOrDefault()
会返回每个组中的第一个项目(即用户),如果该组为空,则返回null
。
listOfImages.SelectMany(image => image.Users)
.GroupBy(user => user)
.OrderByDescending(group => group.Count())
.Take(3)
.Select(group => group.FirstOrDefault())
这应该有希望实现你想要的。我建议您阅读LINQ,以便了解其所有方法的工作原理 - 一旦您知道如何使用它,它就非常有用。稍微玩一下,这样你就能感受到它 - 像OrderBy
和Take
这样的方法非常明显,其他像SelectMany
这样的方法并不那么明显。