2010-08-10 7 views
8

Decidí probar LINQ por primera vez para intentar y resolver this question.Pimp my LINQ: un ejercicio de aprendizaje basado en otra publicación

Los resultados de mi primera incursión en el maravilloso mundo de LINQ eran los siguientes:

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

me gustaría saber cómo puedo mejorar la solución anterior a este pequeño ejemplo artificioso. No estoy demasiado interesado en si he usado el mejor método de validación, o cómo puedo localizar "Presione Enter" o algo por el estilo; Solo me interesa usar este ejemplo para aprender un poco más sobre LINQ.

+2

+1 para el título:} –

+0

@serkan - hecho. alguien tiene que sacar un libro con ese título – Matt

+0

es una frase de comedia cliché ido gracioso otra vez –

Respuesta

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

donde s.Count (x => x == '-') == 2 Pero totalmente. – Toby

+0

ahh que sería una expresión lambda, luego –

+0

, de hecho, todo el linq se convierte en lambda mientras está compilado. Intenta mirarlo en el reflector. – nothrow

4

También se puede escribir usando expresiones lambda:

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

prefiero expresiones lambda más de sintaxis LINQ debido a la interfaz fluida. En mi humilde opinión es más humana legible.

+0

¿Interfaz fluida? –

+0

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

+0

En general, se implementa una interfaz fluida mediante el uso de un método de encadenamiento para retransmitir el contexto de instrucción de una llamada posterior. (Un poco más complicado que eso, pero lo hará por ahora) En este caso, el método Where se llama y luego se llama al método Select. – heads5150

4

Esto es bastante agradable, creo. Parcialmente LINQ.

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

Si no puede haber ningún '-' después de los dos primeros, entonces no sucederá (no 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

bueno, pero consume más memoria, que la variante .Substring. – nothrow

+1

Hice var result = de s en la lista seleccione String.Join ("", s.Split ('-'). Skip (2)); Excelente idea, pero se está enganchando en las entradas de arenque rojo (por ejemplo, "xxxx") –

+0

@Yossarian Sí, tienes razón en eso.Pero debe ser más rápido que Reg exp y creo que es muy elegante sintácticamente. Si quieres el más rápido posible, no debes usar LINQ de manera más imperativa. –

4

Soy un gran fan de Lambdas también ...

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

no creo que esto es una mejora, ya que es menos fácil de leer, pero se puede hacer todo en una sola línea utilizando algunos de los métodos incorporados en la clase de lista:

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

Personalmente encuentro esto bastante horrible, ¡así que es solo por interés!

+0

¡Pero es divertido! El mío es bastante similar, buen uso de FindAll también – fletcher

+0

solo por la legibilidad. Me gustaría haber puesto "list.FindAll (s => s.ToCharArray(). Donde (c => c == '-'). Count() = = 2) "todo en una línea, pero gracias, tu solución me hizo pensar en lambdas y delegados. Creo que los entiendo un poco mejor ahora. –

Cuestiones relacionadas