Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to capture the index value in a LINQ Where method in C#?

Tags:

c#

linq

My following C# code is obviously a hack so how do I capture the index value in the Where method?

     string[] IntArray = { "a", "b", "c", "b", "b"};
                    int index=0;
                    var query = IntArray.Where((s,i) => (s=="b")&((index=i)==i));

    //"&" and "==i" only exists to return a bool after the assignment ofindex

    foreach (string s in query)
                {
                    Console.WriteLine("{0} is the original index of {1}", index, s);
                }
//outputs...
//1 is the original index of b
//3 is the original index of b
//4 is the original index of b
like image 439
David Smith Avatar asked Apr 29 '09 20:04

David Smith


People also ask

How do you find the index of an element in Linq?

LINQ does not have an IndexOf method. So to find out index of a specific item we need to use FindIndex as int index = List. FindIndex(your condition); 0.

Do lists have indexes C#?

The IndexOf method returns the first index of an item if found in the List. C# List<T> class provides methods and properties to create a list of objects (classes). The IndexOf method returns the first index of an item if found in the List.

What is where in C#?

The where clause is used in a query expression to specify which elements from the data source will be returned in the query expression. It applies a Boolean condition (predicate) to each source element (referenced by the range variable) and returns those for which the specified condition is true.


1 Answers

The Where method only returns whether or not the item should be included in the result or not. The function can't provide any more information in a sensible way (it could capture a local variable and do stuff with it, but that would be horrible).

If you want the index in the final result, you'll need to create a projection which includes that index. If you want the original index in the final result, you'll need to put that projection before any Where clauses.

Here's an example of that:

using System;
using System.Collections.Generic;
using System.Linq;

public class Test
{
    static void Main()
    {
        IEnumerable<char> letters = "aBCdEFghIJklMNopQRsTUvWyXZ";

        var query = letters.Select((c, i) => 
                                   new { Char=c, OriginalIndex=i })
                           .Where(x => char.IsLower(x.Char))
                           .Select((x, i) =>
                                   new { x.Char,
                                         x.OriginalIndex,
                                         FinalIndex=i});

        foreach (var result in query)
        {
            Console.WriteLine(result);
        }
    }
}

Results:

{ Char = a, OriginalIndex = 0, FinalIndex = 0 }
{ Char = d, OriginalIndex = 3, FinalIndex = 1 }
{ Char = g, OriginalIndex = 6, FinalIndex = 2 }
{ Char = h, OriginalIndex = 7, FinalIndex = 3 }
{ Char = k, OriginalIndex = 10, FinalIndex = 4 }
{ Char = l, OriginalIndex = 11, FinalIndex = 5 }
{ Char = o, OriginalIndex = 14, FinalIndex = 6 }
{ Char = p, OriginalIndex = 15, FinalIndex = 7 }
{ Char = s, OriginalIndex = 18, FinalIndex = 8 }
{ Char = v, OriginalIndex = 21, FinalIndex = 9 }
{ Char = y, OriginalIndex = 23, FinalIndex = 10 }
like image 142
Jon Skeet Avatar answered Oct 06 '22 00:10

Jon Skeet