Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Splitting List<T> based on comma separated property value using Linq

Tags:

c#

linq

Given this class:

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

Suppose I have the following List<Article> where some of the articles contain a comma separated name:

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

Is there a way, in one Linq statement, to get a list where each comma separated name becomes a separate article?

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" },
}
like image 696
Sergi Papaseit Avatar asked Sep 04 '15 15:09

Sergi Papaseit


1 Answers

You can do it with SelectMany:

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

Demo.

I was hoping there was a way that would save me newing-up an object since my class [...] has quite a bit more than two properties

Although you cannot avoid new-ing altogether, you can improve readability of your code quite a bit by hiding the copying of individual properties inside the Article, like this:

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

Now your LINQ would look like this:

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

This did not remove any code, simply reshuffled some of it. However, placing the copying of Article's properties into Article reduces the chance that you wold forget to copy newly added properties.

like image 52
Sergey Kalinichenko Avatar answered Nov 05 '22 08:11

Sergey Kalinichenko