列表中的笛卡尔产品

时间:2019-02-10 22:53:00

标签: c#

由于编译错误,我正在努力创建列表的笛卡尔积。

如果输入是IEnumerable,则extension方法可以处理,但是如果它是列表,则比较麻烦。

返回类型必须为列表。

以下代码在sequence上引发了编译错误

public static List<List<T>> CartesianProduct<T>(this List<List<T>> sequences, Func<T, T> aggregateFunct)
{
    List<List<T>> emptyProduct = new List<List<T>> { new List<T>() };
    return sequences.Aggregate(
      emptyProduct,
      (accumulator, sequence) =>
        from accseq in accumulator
        from item in sequence // CS1943
        select accseq.AddRange(new List<T> { aggregateFunct(item) }));
}

任何帮助将不胜感激。

Severity Code Description Project File Line Suppression State Error CS1943 An expression of type 'List<T>' is not allowed in a subsequent from clause in a query expression with source type 'List<List<T>>'. Type inference failed in the call to 'SelectMany'. Maths ...\Maths.cs 17 Active

2 个答案:

答案 0 :(得分:3)

我不明白您为什么要更改方法。它可以在任何IEnumerable<T>上使用,而不仅仅是List<T>。 如果您需要列表列表,只需对结果调用.ToList()

...CartesianProduct().Select(x => x.ToList()).ToList();

并保持原始方法不变

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
    IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
    return sequences.Aggregate(emptyProduct,
        (accumulator, sequence) =>
            from acc in accumulator
            from item in sequence
            select acc.Concat(new[] { item }));
}

答案 1 :(得分:0)

问题是AddRange返回void,因此您的select语句无效。您可以创建类似于AddRange并具有返回值的扩展方法,并按照

的说明更新代码
private static List<T> AddRangeReturn<T>(this List<T> list, IEnumerable<T> items)
{
    list.AddRange(items);

    return list;
}

public static List<List<T>> CartesianProduct<T>(List<List<T>> sequences, Func<T, T> aggregateFunct)
{
    List<List<T>> emptyProduct = new List<List<T>> { new List<T>() };
    return sequences.Aggregate(
        emptyProduct,
        (accumulator, sequence) =>
            (from accseq in accumulator
            from item in sequence // CS1943
            select accseq.AddRangeReturn(new List<T> { aggregateFunct(item) })).ToList());
}