2010-08-10 11 views
8

Ich entschied mich, LINQ zum ersten Mal versuchen zu versuchen und zu lösen this question.Pimp meine LINQ: eine Lernübung basierend auf einem anderen Beitrag

Die Ergebnisse meiner ersten Ausflug in die wunderbare Welt der LINQ sah wie folgt aus:

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

Ich mag gerne wissen, wie ich die obige Lösung für dieses erfundene kleines Beispiel zu verbessern. Ich bin nicht sehr daran interessiert, ob ich die beste Validierungsmethode verwendet habe oder wie ich "Press Enter" oder etwas Ähnliches lokalisieren kann. Ich bin nur daran interessiert, dieses Beispiel zu verwenden, um ein wenig mehr über LINQ zu lernen.

+2

+1 für Titel:} –

+0

@serkan - Fakt. jemand muss ein Buch mit diesem Titel herausbringen – Matt

+0

es ist ein Klischee Comedy-Satz wieder lustig geworden –

Antwort

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

wo ändern s.Count (x => x == '-') == 2 Aber total. – Toby

+0

ahh, das wäre ein Lambda-Ausdruck, dann –

+0

in der Tat wird ganze linq während kompiliert in Lambda konvertiert. Versuche es im Reflektor zu sehen. – nothrow

4

Es kann auch Lambda-Ausdrücke verwenden geschrieben werden:

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

ziehe ich Lambda-Ausdrücke über LINQ-Syntax, weil der Fluent-Benutzeroberfläche. IMHO ist es menschlicher lesbar.

+0

Fließende Schnittstelle? –

+0

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

+0

Im Allgemeinen wird eine flüssige Schnittstelle implementiert, indem Methodenverkettung verwendet wird, um den Anweisungskontext weiterzuleiten eines nachfolgenden Anrufs. (Ein bisschen mehr als das, aber es wird für jetzt tun) In diesem Fall wird die Methode Where aufgerufen, dann wird die Methode Select aufgerufen. – heads5150

4

Das ist ziemlich schön, denke ich. Teilweise LINQ.

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

Wenn kann es keine sein '-' nach den ersten beide dann dies tun wird (nicht 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

schön, aber verbraucht mehr Speicher als .Substring-Variante. – nothrow

+1

Ich tat var Ergebnis = von s in Liste wählen Sie String.Join ("", am Split ('-'). Überspringen (2)); Großartige Idee, aber es ist auf den roten Hering Einträge (z. B. "xxxx") –

+0

@Yossarian Ja, Sie haben richtig damit.Aber es muss schneller sein als Reg exp und ich denke, es ist syntaktisch ziemlich glatt. Wenn Sie schnellstmöglich arbeiten möchten, sollten Sie LINQ nicht unbedingt verwenden, sondern unbedingt. –

4

Ich bin ein großer Fan von Lambda zu ...

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

ich glaube nicht, das ist eine Verbesserung, da es weniger lesbar ist, aber man kann sie alle in einer Zeile tun einige der eingebauten Methoden in der List-Klasse verwenden:

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

Persönlich finde ich das ziemlich schrecklich, also ist es nur für das Interesse!

+0

Aber es macht Spaß! Meins ist ziemlich ähnlich, gute Verwendung von FindAll zu – fletcher

+0

nur für die Lesbarkeit hätte ich "list.FindAll (s => s.ToCharArray(). Wobei (c => c == '-'). Count() = = 2) "Alles auf einer Linie, aber danke, Ihre Lösung brachte mich dazu, über Lambdas und Delegierte nachzudenken. Denke, ich verstehe sie jetzt ein bisschen besser. –

Verwandte Themen