I have a list of attribute values that look like this:
public class AttributeOption
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class MyAttribute
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<AttributeOption> Options { get; set; } = new List<AttributeOption>();
}
I have a list of attributes i.e. var attributes = new List<MyAttribute>();
and the list contains three sets of attributes e.g. color, size and gender. Each attribute has its options. For example, color has red, white and blue options. Size has small, medium and large and finally gender has male and female.
How do I generate a cartesian product of all these attributes? I should end up with:
Red-Small-Male
Red-Small-Female
Red-Medium-Male
...
White-Small-Male
White-Small-Female
...
>Solution :
From this answer and this later answer, you can use an extension method to generate the Cartesian Product of an arbitrary number of sequences:
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) =>
sequences.Aggregate(Enumerable.Empty<T>().AsSingleton(),
(accumulator, sequence) => accumulator.SelectMany(prodSoFar => sequence.Select(prodSoFar.Append)));
public static IEnumerable<T> AsSingleton<T>(this T item) => new[] { item };
Using this extension method, you can use LINQ to generate your desired answer.
var ans = attributes.Select(a => a.Options.Select(o => o.Name))
.CartesianProduct()
.Select(s => String.Join("-", s))
.ToList();