Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

310
Views
Get index of nth element with specific condition

Let us say we have a List<int> with content like [0,0,0,0,1,1,1,1,0,0,0,1,2,2,0,0,2,2] and we want to have the index of the nth number that is not zero.

For example, GetNthNotZero(3) should return 6.

It would be easy with a for loop, but I feel there should be a LINQ to accomplish that. Is that possible with a LINQ statement?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

There isn't an out of the box method, but have you considered writing your own extension method to provide something similar to LINQ's FindIndex()?

class Program
{
    static void Main(string[] args)
    {
        var list = new List<int>{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 2, 2, 0, 0, 2, 2 };

        var index = list.FindNthIndex(x => x > 0, 3);
    }
}

public static class IEnumerableExtensions
{
    public static int FindNthIndex<T>(this IEnumerable<T> enumerable, Predicate<T> match, int count)
    {
        var index = 0;

        foreach (var item in enumerable)
        {
            if (match.Invoke(item))
                count--;
            if (count == 0)
                return index;
            index++;
        }

        return -1;
    }
}
over 4 years ago · Santiago Trujillo Report

0

Actually you can do that with standard LINQ, you can use:

List<int> sequence = new List<int>{0,0,0,0,1,1,1,1,0,0,0,1,2,2,0,0,2,2};
int index = sequence.Select((x, ix) => (Item:x, Index:ix))
    .Where(x => x.Item != 0)
    .Skip(2)  // you want the 3rd, so skip 2
    .Select(x => x.Index)
    .DefaultIfEmpty(-1) // if there is no third matching condition you get -1
    .First(); // result: 6
over 4 years ago · Santiago Trujillo Report

0

This is certainly possible, but the Linq approach will make it much more complicated. This is one of those cases where an explicit loop is much better.

Two significant complications arising from using Linq are:

  1. Handling an empty sequence or a sequence with no zeros.
  2. Synthesizing an index to use.

A Linq solution might look like this (but note that there are probably many different possible approaches using Linq):

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

public static class Program
{
    public static void Main()
    {
        var ints = new List<int> { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 2, 2, 0, 0, 2, 2 };

        Console.WriteLine(IndexOfNthNotZero(ints, 3));                     // 6
        Console.WriteLine(IndexOfNthNotZero(Enumerable.Repeat(0, 10), 3)); // -1
        Console.WriteLine(IndexOfNthNotZero(ints, 100));                   // -1
        Console.WriteLine(IndexOfNthNotZero(Array.Empty<int>(), 0));       // -1
    }

    public static int IndexOfNthNotZero(IEnumerable<int> sequence, int n)
    {
        return sequence
            .Select((v, i) => (value:v, index:i))       // Synthesize the value and index.
            .Where(item => item.value != 0)             // Choose only the non-zero value.
            .Skip(n-1)                                  // Skip to the nth value. 
            .FirstOrDefault((value:0, index:-1)).index; // Handle missing data by supplying a default index of -1.
    }
}

Note that this implementation returns -1 to indicate that a suitable value was not found.

Compare that with a simple loop implementation and I think you'll agree it's better to use a simple loop!

public static int IndexOfNthNotZero(IReadOnlyList<int> sequence, int n)
{
    for (int i = 0; i < sequence.Count; ++i)
        if (sequence[i] != 0 && --n == 0) // If element matches, decrement n and return index if it reaches 0.
            return i;

    return -1;
}

Or alternatively if you prefer (avoiding predecrement):

public static int IndexOfNthNotZero(IReadOnlyList<int> sequence, int n)
{
    for (int i = 0, numberOfMatches = 0; i < sequence.Count; ++i)
    {
        if (sequence[i] != 0)           // If condition matches
            if (++numberOfMatches == n) // Increment number of matches, and if it reaches n
                return i;               // then return the current index
    }

    return -1;
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!