属性值在单个列表中的笛卡尔积

huangapple go评论75阅读模式
英文:

Cartesian product of attribute values in single list

问题

我有一个属性值列表,看起来像这样:

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

我有一个属性列表,例如 var attributes = new List<MyAttribute>();,该列表包含三组属性,例如颜色、尺寸和性别。每个属性都有其选项。例如,颜色有红色、白色和蓝色选项。尺寸有小号、中号和大号,最后性别有男性和女性。

如何生成这些属性的笛卡尔积?我应该得到:

红色-小号-男性
红色-小号-女性
红色-中号-男性
...
白色-小号-男性
白色-小号-女性
...
英文:

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&lt;AttributeOption&gt; Options { get; set; } = new List&lt;AttributeOption&gt;();
}

I have a list of attributes i.e. var attributes = new List&lt;MyAttribute&gt;(); 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
...

答案1

得分: 0

以下是您要翻译的内容:

这个答案这个后续答案中,您可以使用扩展方法来生成任意数量序列的笛卡尔积:

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

使用这个扩展方法,您可以使用LINQ生成所需的答案:

var ans = attributes.Select(a => a.Options.Select(o => o.Name))
                    .CartesianProduct()
                    .Select(s => String.Join("-", s))
                    .ToList();

请注意,代码部分不会进行翻译。

英文:

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&lt;IEnumerable&lt;T&gt;&gt; CartesianProduct&lt;T&gt;(this IEnumerable&lt;IEnumerable&lt;T&gt;&gt; sequences) =&gt;
    sequences.Aggregate(Enumerable.Empty&lt;T&gt;().AsSingleton(),
                        (accumulator, sequence) =&gt; accumulator.SelectMany(prodSoFar =&gt; sequence.Select(prodSoFar.Append)));
public static IEnumerable&lt;T&gt; AsSingleton&lt;T&gt;(this T item) =&gt; new[] { item };

Using this extension method, you can use LINQ to generate your desired answer.

var ans = attributes.Select(a =&gt; a.Options.Select(o =&gt; o.Name))
                    .CartesianProduct()
                    .Select(s =&gt; String.Join(&quot;-&quot;, s))
                    .ToList();

huangapple
  • 本文由 发表于 2023年2月9日 03:07:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75390594.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定