I am trying to figure out how to create a single concatenated list using C#, originating from 3 separate lists. For example:
List 1: Ugly, Pretty
List 2: Dogs, Carts, Pigs
List 3: Rock, Suck
Output:
Ugly Dogs Rock
Ugly Dogs Suck
Ugly Cats Rock
Ugly Cats Suck
Ugly Pigs Rock
Ugly Pigs Suck
Pretty Dogs Rock
Pretty Dogs Suck
Pretty Cats Rock
Pretty Cats Suck
Pretty Pigs Rock
Pretty Pigs Suck
I know it is just nested loops, but the part I cant figure out is how to use List-strings for each list.
var list = from s1 in list1
from s2 in list2
from s3 in list3
select s1 + " " + s2 + " " + s3;
Isn't it a Cartesian product?
var r = from i1 in list1
from i2 in list2
from i3 in list3
select new { i1, i2, i3 };
// or String.Format("{0} {1} {2}", i1, i2, i3);
List<string> list1 = new List<string>(){ "Ugly", "Pretty"};
List<string> list2 = new List<string>(){ "Dogs", "Carts", "Pigs"};
List<string> list3 = new List<string>(){ "Rock", "Suck"};
var result = from s1 in list1
from s2 in list2
from s3 in list3
select new[] { s1, s2, s3 };
foreach (var item in result)
{
Console.WriteLine(String.Join(",", item));
}
If you are looking for a more general solution, not only for 3 lists you may try Eric Lippert's solution
foreach (var item in new[] { list1, list2, list3 }.CartesianProduct())
{
Console.WriteLine(String.Join(",", item));
}
public static partial class MyExtensions
{
// Eric Lippert’s Blog
// Computing a Cartesian Product with LINQ
// http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
// base case:
IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
foreach (var sequence in sequences)
{
var s = sequence; // don't close over the loop variable
// recursive case: use SelectMany to build the new product out of the old one
result =
from seq in result
from item in s
select seq.Concat(new[] { item });
}
return result;
}
}