2015-09-04 2 views
5

Dato questa classe:Lista Splitting <T> sulla base di una virgola il valore della proprietà separata utilizzando Linq

public class Article 
{ 
    public string Name { get; set; } 
    public string Colour { get; set; } 
} 

Supponiamo che io ho il seguente List<Article> in cui alcuni degli articoli contengono una virgola nome separato:

var list = new List<Article> 
{ 
    new Article { Name = "Article1, Article2, Article3", Colour = "Red" }, 
    new Article { Name = "Article4, Article5, Article6", Colour = "Blue" }, 
} 

Is c'è un modo, in una dichiarazione Linq, di ottenere una lista in cui ogni nome separato da virgola diventa un articolo separato?

var list = new List<Article> 
{ 
    new Article { Name = "Article1", Colour = "Red" }, 
    new Article { Name = "Article2", Colour = "Red" }, 
    new Article { Name = "Article3", Colour = "Red" }, 
    new Article { Name = "Article4", Colour = "Blue" }, 
    new Article { Name = "Article5", Colour = "Blue" }, 
    new Article { Name = "Article6", Colour = "Blue" }, 
} 

risposta

7

È possibile farlo con SelectMany:

var res = list.SelectMany(
    art => art.Name.Split(',').Select(n => 
     new Article { 
      Name = n.Trim() 
     , Colour = art.Colour 
     } 
    ) 
); 

Demo.

Speravo ci fosse un modo che potrebbe salvarmi Newing-up di un oggetto dal momento che la mia classe [.. .] ha un bel po 'più di due proprietà

Anche se non si può evitare new -ing del tutto, è possibile migliorare la leggibilità del codice un po 'nascondendo la copia dei singoli immobili all'interno del Article, in questo modo:

public class Article { 
    public string Name { get; set; } 
    public string Colour { get; set; } 
    public Article Rename(string newName) { 
     return new Article { 
      Name = newName 
     // Copy the remaining attributes 
     , Colour = this.Colour 
     }; 
    } 
} 

Ora il vostro LINQ sarebbe simile a questa:

var res = list.SelectMany(art => art.Name.Split(',').Select(n => art.Rename(n.Trim()))); 

Questo non ha rimosso alcun codice, semplicemente rimescolato alcuni di esso. Tuttavia, collocare la copia delle proprietà di Article in Article riduce le possibilità che si dimentichi di copiare le proprietà appena aggiunte.

+0

Brillante, grazie. Mi sono avvicinato molto a qualcosa di molto simile a questo, ma speravo che ci fosse un modo per salvarmi dal creare un oggetto dato che la mia classe è un DTO e, come puoi immaginare, ha un bel po 'più di due proprietà;) –

+0

@SergiPapaseit Questa è una buona osservazione. Sebbene non sia possibile evitare del tutto "nuovo", è possibile ristrutturare il codice per una migliore manutenibilità. – dasblinkenlight

+0

Approccio pulito. Ti inviterò di nuovo se potessi;) Quello che ho finalmente fatto è piegare il bit di trasformazione di linq all'interno di un metodo di estensione. –