7
votes

Utilisation de LINQ pour extraire des intents d'une liste des chaînes

J'ai une liste code> et certaines de ces chaînes sont des chiffres. Je veux extraire ce sous-ensemble dans une liste code>.

Je l'ai fait de manière assez verbeuse, comme ci-dessous - comme ci-dessous - mais je reçois le sentiment qu'il doit y avoir un NATATER LINQ WAY de structurer cela. TOUTES IDÉES? P>

List<string> myStrs = someListFromSomewhere;
List<int> myInts = new List<int>();

foreach (string myStr in myStrs)
{
    int outInt;
    if (int.TryParse(myStr, out outInt))
    {
        myInts.Add(outInt);
    }
}


3 commentaires

Une autre occasion pour moi d'indiquer "J'aimerais que Tryparse retournerait un int?" (Je sais, hérité ...)


certainement pas plus efficace, mais vous pouvez faire var mytints = mystrs.herwhere (S => int.tryparse (s, sortie tint)). Sélectionnez (S => int.parse (s)) , Tant que vous aviez déjà une sortie définie. Cela appelle tryparse et analyse sur chaque chaîne, alors je ne le suggérerais pas vraiment


Cette question pourrait intéresser: Requête LINQ Pour effectuer une projection, sauter des cas où la projection provoquerait une exception , j'utilise votre cas exact comme exemple.


4 Réponses :


23
votes

Vous pouvez le faire comme ceci:

int parsed = 0;

myInts = myStrs.Where(x => int.TryParse(x, out parsed)).Select(x => parsed);


9 commentaires

@DTB: Pas du tout. Si c'est le cas, vous ne comprenez pas vraiment le fonctionnement interne de Linq.


Il suffit de dire que cela nécessite une trop grande connaissance du fonctionnement interne de Linq à mon goût.


De toute évidence, cela dépend de combien vous savez de toute façon. L'une des caractéristiques principales de LINQ est son exécution différée. Et après tout, l'OP a voulu apprendre sur Linq.


Linq-to-objets, c'est-à-dire. Votre code rompre avec Asparallel () alors que le mien fonctionnerait.


@DTB: Mais c'est génial, car l'OP dit "c'est principalement pour ma linq Education ".


Tu m'as battu! Une chose que: lorsque j'ai essayé cela, le compilateur s'est plaint de la variable analysé non initialisé, donc je l'initialise à 0 . Après cela, la solution fonctionne comme un charme.


C'est une solution compliquée, ce n'est pas clair pour la personne qui appuiera ce code.


Merci - c'est ce que je pensais exister.


Wow, Linq est cool. Cette solution m'a enfin convaincu que je devais arrêter de jouer et commencer à apprendre Linq.



7
votes

LINQ et OUT CODE> Les paramètres ne se mélangent pas bien. Vous pouvez le faire:

var myInts = myStrs
    .Select(s =>
    {
        int outInt;
        return int.TryParse(s, out outInt) ? (int?)outInt : null;
    })
    .Where(i => i.HasValue)
    .Select(i => i.Value)
    .ToList();


4 commentaires

@Danielhilggarth: Oui, pourrait être un peu trop excédant, mais il sera également très clair. J'ai rencontré plus de développeurs qui ne comprennent pas tout à fait les effets de l'exécution différée (ou sont même conscients de son existence) que ceux qui le font.


@ Fredrikmörk: assez juste. Mais dans ce cas, n'utilisez pas Linq du tout et utilisez la boucle classique que l'OP a déjà. Ce n'est pas plus de code et il est encore plus lisible que la solution fournie par DTB.


@Danielhilgarth: Je vois ton point, et c'est un bon. Je pense généralement que l'apprentissage vient en marche. Se déplacer dans Linq implique potentiellement de nombreux nouveaux concepts (tels que Lambdas, méthodes anonymes, exécution différée). Votre solution (très élégante, BTW) en utilise beaucoup d'entre eux en même temps. Cela pourrait être bon, mais cela pourrait aussi être écrasant en fonction du point de départ du lecteur. Je ne dis pas que vous avez tort (tout le contraire), mais comme un outil d'apprentissage, cela pourrait très bien être une étape valable.


@ Fredrikmörk: Je suis d'accord avec ce que vous dites. Ma principale préoccupation lors de l'affichage de ce commentaire était que quelqu'un voit cette réponse et l'emporte comme le meilleur moyen de le faire, surtout quand il provient d'un membre respecté avec une grande réputation. Utilisation de LINQ Ce n'est pas le cas, il peut être fait mieux (= plus court, plus facile à comprendre si vous comprenez LINQ). En effet, il s'agit d'une étape valable dans l'apprentissage de Linq, mais seulement un intermédiaire et non le dernier.



0
votes

Puisque ceci est pour Linq Education ... Si vous cherchez vraiment comment cela peut être fait avec seulement la syntaxe LINQ, une autre option consiste à déplacer la logique analysante à une classe qui encapsule le résultat et la valeur.

class Parser
{
        public bool IsInt { get; set; }
        public int Val { get; set; }

        public Parser(string val)
        {
            int outVal;
            IsInt = int.TryParse(val, out outVal);
            if (IsInt)
            {
                Val = outVal;
            }
        }
}


0 commentaires

0
votes

Sélectionnez Distinct puis analyser chaque élément sélectionné

List<int> myInts = new List<int>();
myInts = myStrs.Distinct().Select(
    x =>
    {
        int parsed;
        int.TryParse(x, out parsed);
        return parsed;
    })  
.ToList();


0 commentaires