获取现有列表的所有子列表的可枚举

Get an enumerable of all sub lists of an existing list

我有一个List<T>,我想获取所有可能的子列表,例如:

[A, B, C, D, E] => [[A], [A, B], [A, B, C], [A, B, C, D], [A, B, C, D, E]]

有没有简单的方法来使用 LINQ to Objects 获取这个新的枚举?

编辑 1: 请注意,我只想要 "prefix lists",而不是所有可能的排列(即,显示的示例结果已经完成)。

编辑 2: 请注意,我也想保持元素的顺序。

编辑 3: 有没有办法在 O(n) 而不是 O(n²) 中获取可枚举项,即通过仅迭代一次而不是多次遍历源并返回某种 view on每次都是数据而不是新列表?

是的,你是对的,你的要求是与排列无关的排列的一小部分。所以我的建议是:

var result = Enumerable.Range(1, list.Count).
                Select(i => list.Take(i).ToList()).
                ToList();

您可以遍历列表中的项目数量范围和 select 子列表,如下所示:

var list = new List<string> { "A", "B", "C", "D", "E"};

var query =
    from i in Enumerable.Range(1, list.Count)
    select list.Take(i);

请记住,如果您的数据不在 List<T> Count 中,可能会很昂贵。另请记住,这会多次迭代您的数据。

一个非常幼稚的扩展方法:

public static class Extensions
{
    public static IEnumerable<IEnumerable<T>> GetOrderedSubEnumerables<T>(
                                              this IEnumerable<T> collection)
    {
        var builder = new List<T>();
        foreach (var element in collection)
        {
            builder.Add(element);
            yield return builder;
        }
    }
}

使用:

void Main()
{
    var list = new List<string> { "A", "B", "C", "D", "E" };
    Console.WriteLine(list.GetOrderedSubEnumerables());
}

结果:

请注意,这将在您迭代集合时查看您的数据 return。但最终,如果您需要单独使用每个排列,则需要在返回之前复制每个 List<T>。在那种情况下,应该这样做:

public static class Extensions
{
    public static IEnumerable<IEnumerable<T>> GetOrderedSubEnumerables<T>(
                                              this IEnumerable<T> collection)
    {
        var builder = new List<T>();
        foreach (var element in collection)
        {
            builder.Add(element);
            var local = new List<T>(builder);
            yield return local;
        }
    }
}