11
votes

Expression Lambda pour obtenir des index de la liste des articles conditionnellement

J'ai une liste code>. J'ai besoin d'obtenir les index des éléments top n où la valeur de l'article = true.

Par exemple, les éléments de liste suivants (BOOL) P>

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 


0 commentaires

4 Réponses :


0
votes

Cela devrait probablement le faire.

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);
} 


2 commentaires

Cela donnera juste vrai, vrai, vrai, vrai ... compte fois. Cela ne donne pas aux indices .


Désolé, je l'ai vu aussi et corrigé.



37
votes

Eh bien, en supposant que vous avez une condition facile à identifier, vous pouvez faire quelque chose comme ceci, ce qui fonctionnera pour tout ienumerable : xxx < / Pré>

(Complétez évidemment le bit approprié du clause. Si c'est juste une liste il peut simplement être x => x.value .)

Les bits importants sont que vous utilisez la surcharge de Sélectionnez pour obtenir des paires index / valeur avant le < code> où , puis un autre sélectionnez pour obtenir juste les index après le ... et utilisez prendre Pour obtenir uniquement les résultats n .


10 commentaires

Nice, je ne savais pas que vous pourriez faire choisir ((val, ind) => ...). +1


@Alxandr: C'est l'une des choses que vous pouvez faire en appelant la méthode directement, mais pas via une expression de requête.


Donc, il n'ya aucun moyen d'obtenir l'index dans un motif de requête (sauf la façon dont je l'ai fait en comptant simplement à l'extérieur)?


Je veux dire, cela pourrait probablement être écrit comme à partir de l'élément dans la liste, let Index = Ind ++ où condition (élément) Sélectionnez Index; ou quelque chose comme ça, non?


@Jon Que recommanderiez-vous de lire pour les arbres d'expression et d'expression de Lambda ... pour obtenir des compétences d'experts?


@ALXANDR: Vous devriez déclarer Index en dehors de la requête, puis vous auriez une requête latérale qui n'est généralement pas agréable.


@Ramiz: Je recommanderais de pratiquer plus que toute autre chose. Les Lambdas ne sont pas vraiment difficiles - mais ils prennent un certain état d'esprit.


@Merci jon. Je vais. Devrais-je envisager une lecture / ressource pendant la pratique?


@Jonskeet: Est-il possible d'avoir une valeur de valeur de valeur par défaut pour l'index? quelque chose comme source.select ((valeur, index = 10) => ... ?


@HumptyDumpty: Non, mais vous pouvez utiliser (valeur, index) => nouvelle valeur {valeur, index + 10} . Notez que ces jours, je suggère d'utiliser un littéral de valeur, donc (valeur, index) => (valeur, index: index + 10)



2
votes

Il y a une surcharge de SELECT CODE> où la Lambda obtient deux paramètres: l'index et l'élément. Donc, vous pouvez simplement prendre les indices où la valeur est vraie, fournissant une sentinelle (ici, -1) pour ceux que vous ne voulez pas. Puis filtrez les sentinelles et prenez combien vous voulez:

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


1 commentaires

Vous avez l'index et l'élément dans l'ordre inverse de votre Lambda, qui confondra les gens (me confondes). Il devrait être SELECT ((VAL, IX) ... .



-1
votes

ici comment ça se passe:

  1. Sélectionnez Source + Son index
  2. Ajouter une condition au où la clause (la source de la clause WHERE contient maintenant la source source d'origine + index )
  3. Sélectionnez l'index (l'index renvoyé ici est l'index d'origine de la source d'origine)

    var indexes = INPUTLIST.Sélectionnez (((entrée, index) => Nouvelle entrée {entrée, index}). Où (a => condition (A.Input)). Sélectionnez (A => A.Idex) ;


0 commentaires