Splitting a <T> List Based on a Comma Separated Property Value Using 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 a single Linq expression to get a list in which 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" }, } 
+5
source share
1 answer

You can do this with SelectMany :

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

Demo version

I was hoping there was a way that would save me when creating an object, since my class [...] has a little more than two properties

Although you cannot avoid new -ing at all, you can slightly improve the readability of your code by hiding the copying of individual properties inside Article , for example:

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

Your LINQ will now look like this:

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

This did not remove any code, just shuffled some of them. However, placing a copy of the Article properties in Article reduces the likelihood that you wold forgot to copy the newly added properties.

+7
source

All Articles