我有一个列表,我正在填写团队的总销售额。
lstTeamSales.OrderBy(x => x.TotalSales);
此列表包含int userID
和decimal totalSales
。
我按totalSales
订购。那时我怎样才能确定登录人的等级?
我知道我可以将用户ID登录的人与列表中的userID进行比较。如果他在销售中排名第3,我需要返回他的等级的int,这将是Rank 3。
答案 0 :(得分:2)
这个问题可以改为"我如何获得IEnumerable中的元素索引"。这是答案:How to get index using LINQ? 以下是如何使用它:
int rank = lstTeamSales.OrderBy(x => x.TotalSales).FindIndex(x => x.userID == currentUserID);
这比基于Select
的方法稍微有效。
看起来LINQ不支持.FindIndex。知道如何实现该功能吗?
我现在可能已经想到了它。我刚刚在ORderBy()之后添加了.ToList()。
无无无无!它杀死了整个想法:(想法是将extension method FindIndex
添加到IEnumerable。然后使用它。参见示例:
static class FindIndexEnumerableExtension
{
public static int FindIndex<T>(this IEnumerable<T> items, Func<T, bool> predicate)
{
if (items == null) throw new ArgumentNullException("items");
if (predicate == null) throw new ArgumentNullException("predicate");
int retVal = 0;
foreach (var item in items)
{
if (predicate(item)) return retVal;
retVal++;
}
return -1;
}
}
class YourClass
{
void YourMethod()
{
lstTeamSales.OrderBy(x => x.TotalSales).FindIndex(x => x.UserID == currentUserID);
}
}
使用FindIndexEnumerableExtension
扩展方法定义类FindIndex
后,您可以在代码中的任何位置使用此方法。您只需要在模块中添加using
指令,其中FindIndexEnumerableExtension
已定义。这基本上就是LINQ的工作原理。
如果您不想使用此解决方案,那么至少在排序之前将lstTeamSales转换为List。并使用List<>.Sort()
方法对其进行排序。
答案 1 :(得分:1)
您可以使用带有Func<TSource, Int32, TResult>
(或等效表达式)的select扩展,如下所示:
var userId = /* the userId */;
lstTeamSales.OrderBy(x => x.TotalSales).Select((x, i) => new
{
x.UserId,
x.TotalSales,
Rank = i + 1
}).FirstOrDefault(x => x.UserId == theUserId);
这将返回一个对象,其中包含用户ID,总销售额和修复用户ID的排名。如果集合中没有null
的实体,它将返回UserId = theUserId
。
索引(示例中的i
)基于0。根据需要进行调整。
答案 2 :(得分:1)
根据总销售额列表lstTeamSales
以及代表您希望找到userSales
排名的销售数字,您需要的是{{1}的总销售数量超过lstTeamSales
。如果它是你想要的等级,那么你可能想要排除等级中的关系(即如果前两个销售数字都是1000,那么它们都被排名为1)
您可以通过仅使用userSales
投放销售数字,删除与Select
电话的关联,然后使用Distinct
来执行此操作:
Count
这将为您提供高于当前用户的总销售数量。从那里,当前用户的排名高于该数字:
lstTeamSales.Select(x => x.TotalSales).Distinct().Count(x => x > userSales)
答案 3 :(得分:0)
Select((item, index) => ...)
表单允许这样做(如Simon所示),但是DMac提及您可能需要考虑重复。要将其合并到Select
,您可以使用GroupBy:
lstTeamSales
.OrderByDescending(x => x.TotalSales).GroupBy(x => x.TotalSales)
.Select((group, i) => new {
Rank = i + 1,
Users = group.Select(x => x.UserId)
})
这将为您提供排名列表以及具有该排名的用户列表。或者您可以使用SelectMany将其展平,以获得每个用户的排名:
lstTeamSales
.OrderByDescending(x => x.TotalSales).GroupBy(x => x.TotalSales)
.SelectMany((x, i) => new {
Rank = i + 1,
User = x.UserId
})
您可以过滤此序列以查找用户,但如果您只想查找特定用户的排名,那么DMac的解决方案是最直接的。例如,如果您想列出前5名卖家(请参阅Take),上述内容会更有用。