代码之家  ›  专栏  ›  技术社区  ›  M Afifi

列表上的笛卡尔积

c#
  •  3
  • M Afifi  · 技术社区  · 5 年前

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

    如果输入是IEnumerable,扩展方法将处理,但是如果输入是一个列表,则会处理。

    返回类型必须是列表。

    下面的代码在上引发编译错误 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 回复  |  直到 5 年前
        1
  •  3
  •   Dennis_E    5 年前

    我不明白你为什么要改变方法。它可以用于任何 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 }));
    }
    
        2
  •  0
  •   Alexander    5 年前

    问题是 AddRange 收益率 void 因此你的 select 语句无效。您可以创建和扩展类似于 阿德兰奇 但使用返回值并按以下方式更新代码

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