vivek singh
vivek singh

Reputation: 121

How to find the index of next matching element in list using LINQ

i have a list say :

List<string> list = new List<string>(){"Oracle","SQL Server","Java","Oracle","Python"};

Now i'm trying to get index of the second "Oracle" from the list using LINQ:

var indexFirefox = list.FindIndex(a => a.Text == "Oracle");

But this will give you only the first instance that is index 0. I want index as 4 in my result. Will using Skip help or there is a more simplistic way of getting the index. The example above is just a demo, i have a list with over 300 values.

Upvotes: 5

Views: 4574

Answers (4)

Sehnsucht
Sehnsucht

Reputation: 5049

So many Linq answer when there already exists one method doing the job (given in the first comment)

List<T>.FindIndex has an overload which takes an additional index parameter to search only from that index.

So to get the second occurrence of an item you just have to use that overload with the result of a "regular" FindIndex.
(Note: in your question's sample you used a.Text but items are string so there is no Text property)

var firstIndex = list.FindIndex (item => item == "Oracle");
if (firstIndex != -1)
{
    var secondIndex = list.FindIndex (firstIndex, item => item == "Oracle");
    // use secondIndex (can be -1 if there is no second occurrence)
}

And with your sample example secondIndex will be 3 (and not 4 as stated in your question, indexes are zero-based)

Alternatively if you want to get occurrence indexes in turn you can loop using that same method.

// defined here to not have to repeat it 
Predicate<string> match = item => item == "Oracle";

for (var index = list.FindIndex (match); index > -1; index = list.FindIndex (index + 1, match))
{
    // use index here
}

Or if you prefer a while loop

var index = list.FindIndex (match);

while (index > -1)
{
    // use index here

    index = list.FindeIndex (index + 1, match);
}

Upvotes: 6

Guy haimovitz
Guy haimovitz

Reputation: 1625

list.Where(x => x == "Oracle").ElementAt(1);
  • Will crash if ther is no second find , you can just check the size of the enumerable before returning second element.

Upvotes: 0

Enigmativity
Enigmativity

Reputation: 117019

This does it nicely for me:

var result =
    list
        .Select((x, n) => new { x, n })
        .Where(xn => xn.x == "Oracle")
        .Select(xn => xn.n)
        .Skip(1)
        .FirstOrDefault();

This gives 3 given the input List<string> list = new List<string>(){"Oracle","SQL Server","Java","Oracle","Python"};.

Upvotes: 0

Sanjay Radadiya
Sanjay Radadiya

Reputation: 1286

here i find index of next of matching element

list.Select((value, index) => new { value, index = index + 1 }).Where(x => x.value == "Oracle").Skip(1).FirstOrDefault().index

Upvotes: 0

Related Questions