在linq集合中获取我的Object位置的巧妙方法

时间:2011-02-17 23:12:15

标签: c# linq

我目前有一个名为Week的对象。一周是Season对象的一部分。这个季节可以包含很多周。我想要做的是找到我周的位置(是本赛季的第一周(所以#1)还是第二周(所以#2)。

int i = 0;
        foreach ( var w in Season.Weeks.OrderBy(w => w.WeekStarts)){
            if(w.Id == Id){
                return i;
            }
            i+=1;
        }

目前这就是我所拥有的。我按照开始日期在一秒钟内订购周,以确保它们的顺序正确。然后我循环使用它们直到找到与我目前正在查看的那一周相匹配的那一周。并返回我一直在计算的int ..

我觉得应该有一个更容易的linq方式来做到这一点,因为它感觉非常混乱!

3 个答案:

答案 0 :(得分:5)

如果您不想编写FindIndex扩展方法或将已排序的项加载到数组/列表中,则可以使用提供项的索引的Select重载:

 return Season.Weeks
              .OrderBy(w => w.WeekStarts)
              .Select((week, index) => new { Week = week, Index = index })
              .First(a => a.Week.Id == Id)
              .Index;

如果无法保证指定的Id将存在,请改为使用FirstOrDefault

var weekIndexTuple = Season.Weeks
                           .OrderBy(w => w.WeekStarts)
                           .Select((week, index) => 
                                    new { Week = week, Index = index })
                           .FirstOrDefault(a => a.Week.Id == Id);

if(weekIndexTuple != null)
{
    return weekIndexTuple.Index;
}
else
{
   // I'm not sure how you want to continue in this case.
   ...      
}

答案 1 :(得分:2)

以下是一个非常相似的问题的答案:How to get the index of an element in an IEnumerable?

许多答案与您已经采用的方式非常相似。将逻辑拉出为扩展方法以分离关注点并更容易重用可能是个好主意。这是上面链接中的Marc Gravell代码:

public static int IndexOf<T>(this IEnumerable<T> source, T value)
{
    int index = 0;
    var comparer = EqualityComparer<T>.Default; // or pass in as a parameter
    foreach (T item in source)
    {
        if (comparer.Equals(item, value)) return index;
        index++;
    }
    return -1;
}

答案 2 :(得分:1)

SLaks为IEnumerable发布了一个简洁的扩展方法,它为您提供了一种从LINQ调用中查找索引的方法:How to get index using LINQ?