2010-11-13 14 views
10

Tengo un List<bool>. Necesito obtener los índices de los elementos n superiores donde el valor del elemento = verdadero.Expresión lambda para obtener índices de elementos de lista condicionalmente

Por ejemplo los siguientes elementos de la lista (bool)

10011001000 

TopTrueIndexes(3) = The first 3 indexes where bits are true are 0, 3, 4 
TopTrueIndexes(4) = The first 4 indexes where bits are true are 0, 3, 4, 7 

¿Cómo puedo escribir una lambda para esto?

Respuesta

30

Bueno, suponiendo que tiene alguna condición fácilmente identificable, se puede hacer algo como esto, que va a trabajar para cualquierIEnumerable<T>:

var query = source.Select((value, index) => new { value, index }) 
        .Where(x => x.value => Condition(value)) 
        .Select(x => x.index) 
        .Take(n); 

(Obviamente, rellene el bit apropiado de la Where cláusula. Si es sólo un List<bool> que sólo puede ser x => x.value.)

los bits son importantes que utilice la sobrecarga de Select para obtener pares índice/valor antes de la Where, y luego otro Select para obtener sólo los índices después de la Where ... Take y utilizar sólo para obtener los primeros resultados n.

+4

Bueno, no sabía que podía hacer Seleccionar ((val, ind) => ...). +1 – Alxandr

+0

@Alxandr: es una de las cosas que puede hacer llamando al método 'Seleccionar' directamente, pero no a través de una expresión de consulta. –

+0

@Jon. Excelente gracias. – Jimmy

0

Esto probablemente debería hacerlo.

IEnumerable<bool> GetItemsInList(IEnumerable<bool> list, int count) { 
    int ind = 0; 
    return list.Select(itm => new {i = ind++, v = itm}).Where(itm => itm.v).Take(count).Select(itm => itm.i); 
} 
+0

Eso solo dará tiempos verdaderos, verdaderos, verdaderos, verdaderos ... 'count'. No está dando los * índices *. –

+0

Lo siento, vi eso también y lo solucioné. – Alxandr

2

Hay una sobrecarga de Select donde la lambda obtiene dos parámetros: el índice y el elemento. De modo que puede tomar los índices donde el valor es verdadero, proporcionando un centinela (aquí, -1) para los que no quiere. A continuación, filtre los centinelas y tome cuántos quiere:

bool[] bools = ...; 
var indices = bools.Select((val, ix) => val ? ix : -1).Where(i => i >= 0).Take(n); 
+0

Tiene el índice y el elemento en orden inverso en su lambda, lo que confundirá a las personas (me confundió). Debería ser 'Seleccionar ((val, ix) ...'. – Mud

Cuestiones relacionadas