2010-08-10 6 views
8

Ho deciso di provare LINQ per la prima volta per provare a risolvere this question.Pimp my LINQ: un esercizio di apprendimento basato su un altro post

I risultati della mia prima incursione nel meraviglioso mondo di LINQ si presentava così:

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

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<string> list = new List<string>() 
      { 
       "fred-064528-NEEDED1", 
       "xxxx", 
       "frederic-84728957-NEEDED2", 
       "sam-028-NEEDED3", 
       "-----", 
       "another-test" 
      }; 

      var result = 
      from s in list 
      where (from c in s where c == '-' select c).Count() == 2 
      select s.Substring(s.LastIndexOf("-") + 1); 

      foreach (string s in result) 
       Console.WriteLine(s); 
      Console.WriteLine("Press Enter"); 
      Console.ReadLine(); 
     } 
    } 
} 

Mi piacerebbe sapere come posso migliorare la soluzione di cui sopra a questo piccolo esempio forzato. Non mi interessa sapere se ho usato il miglior metodo di validazione, o come ho potuto localizzare "Press Enter" o qualcosa del genere; Sono solo interessato a utilizzare questo esempio per imparare un po 'di più su LINQ.

+2

+1 per il titolo:} –

+0

@serkan - fatto. qualcuno ha bisogno di tirar fuori un libro con quel titolo – Matt

+0

è una frase commedia cliched resa divertente ancora –

risposta

6
var result = 
     from s in list 
     where s.Count(x => x == '=') == 2 
     select s.Substring(s.LastIndexOf("-") + 1); 
+1

dove s.Count (x => x == '-') == 2 Ma totalmente. – Toby

+0

ahh che sarebbe un'espressione lambda, quindi –

+0

infatti, l'intero linq viene convertito in lambda mentre è compilato. Cerca di guardarlo nel riflettore. – nothrow

4

Può anche essere scritta utilizzando le espressioni lambda:

var result = 
      list.Where(s => (from c in s where c == '-' select c).Count() == 2).Select(
       s => s.Substring(s.LastIndexOf("-") + 1)); 

preferisco le espressioni lambda oltre sintassi LINQ a causa della interfaccia fluida. IMHO è più leggibile.

+0

Interfaccia fluente? –

+0

ahh: http://stackoverflow.com/questions/214500/which-linq-syntax-do-you-prefer-fluent-or-query-expression –

+0

In genere viene implementata un'interfaccia fluente mediante il concatenamento del metodo per inoltrare il contesto dell'istruzione di una chiamata successiva. (Un po 'più complicato di così, ma lo farà per ora) In questo caso il metodo Dove viene chiamato, allora viene chiamato il metodo Select. – heads5150

4

Questo è abbastanza carino, penso. In parte LINQ.

var result = String.Join("-", inputData.Split('-').Skip(2)); 

Se non ci può essere alcun '-' dopo i primi due allora questo farà (non LINQ):

var result = inputData.Split('-')[2]; //If the last part is NEE-DED then only NEE is returned. And will fail on wrong input 
+0

bello, ma consuma più memoria, rispetto alla variante .Substring. – nothrow

+1

Ho fatto var result = da s nella lista selezionare String.Join ("", s.Split ('-'). Skip (2)); Ottima idea, ma si sta agganciando alle voci di aringhe rosse (ad esempio "xxxx") –

+0

@ Yossarian Sì, hai ragione correttamente su questo.Ma deve essere più veloce di Reg exp e penso che sia abbastanza sintattico. Se vuoi il più veloce possibile, non dovresti usare LINQ ma in modo più imperativo. –

4

Sono un grande fan di Lambda troppo ...

static void Main(string[] args) 
    { 
     Func<string, char, int> countNumberOfCharsInString = 
      (str, c) => str.Count(character => character == c); 

     var list = new List<string>() 
     { "fred-064528-NEEDED1", 
      "xxxx", 
      "frederic-84728957-NEEDED2", 
      "sam-028-NEEDED3", 
      "-----", "another-test" 
     }; 

     list.Where(fullString => countNumberOfCharsInString(fullString,'-') == 2) 
      .ToList() 
      .ForEach(s => Console.WriteLine(s.Substring(s.LastIndexOf("-")+1))); 

     Console.WriteLine("Press Enter"); 
     Console.ReadLine(); 
    } 
4

non credo che questo è un miglioramento, in quanto è meno leggibile, ma si può fare tutto in una riga utilizzando alcuni dei metodi incorporati nella classe List:

list.FindAll(s => s.ToCharArray(). 
    Where(c => c == '-').Count() ==2). 
    ForEach(c => Console.WriteLine(c.Substring(c.LastIndexOf("-") + 1))); 

Personalmente trovo questo piuttosto orribile, quindi è solo per interesse!

+0

Ma è divertente! Il mio è abbastanza simile, buon uso di FindAll anche – fletcher

+0

solo per la leggibilità avrei messo "list.FindAll (s => s.ToCharArray(). Where (c => c == '-'). Count() = = 2) "tutto su una riga, ma grazie, la tua soluzione mi ha fatto pensare a lambda e delegati. Credo di capirli un po 'meglio ora. –

Problemi correlati