开发者

Neat way of gettings position of my Object in linq collections [duplicate]

This question already has answers here: How to get index using LINQ? [duplicate] (7 answers) Closed 8 years ago.

I currently have a object called Week. A week is part of a Season object. the season can contain many weeks. What I want to do is find the position of my week (is it the first week in the season (so #1) or is it the second (so #2).

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

At the moment this is what I have. I order the weeks in a second by there start date to make sure they are in the correct order. and I cycle through them until I find the week that matches the week I am currently looking at. and return the int that I have been counting up..

I feel there should be a easier linq way to do this as it feels pretty messy!


If you prefer not to write a FindIndex extension method or load the sorted items into an array / list, you could use the overload of Select that provides the index of the item:

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

If there's no guarantee that the specified Id will exist, use FirstOrDefault instead:

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.
   ...      
}


Here are answers to a very similar question: How to get the index of an element in an IEnumerable?

A lot of the answers are very similar to the way you're already doing it. It could be a good idea to pull the logic out into an extension method for separation of concerns and for easier reuse. Here's Marc Gravell's code from the link above:

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;
}


SLaks posted a neat extension method for IEnumerables that gives you a method to find the index from within LINQ calls themselves: How to get index using LINQ?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜