Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

306
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda