查找 IEnumerable<T> 集合的二元组组合,C#

Finding 2-Tuple Combinations of IEnumerable<T> collection, C#

我想实现一个方法,它将未知类型的集合作为参数,returns 包含这些元素的所有可能不同组合的二元组集合(无重复) .我的代码:

public static IEnumerable<Tuple<T, T>> Get2Combinations<T>(this 
IEnumerable<T> col)
    {
        /*foreach (var item1 in col)
        {
            col.GetEnumerator().MoveNext();
            foreach (var item2 in col)
            {
                yield return new Tuple<T, T>(item1, item2);
            }
        }*/
        for (int i = 0; i < col.Count(); i++)
        {
            for (int j = i + 1; j < col.Count(); j++)
            {
                yield return new Tuple<T, T>(col.ElementAt(i), 
col.ElementAt(j));
            }
        }
    }

我正在做的是取第一个元素并与其他元素配对。然后使用这个内部 for 循环遍历所有剩余的循环。我看到的问题是方法 col.ElementAt(i)。如果我们查看源代码,我们会发现如果 'col' 是 IList 类型,那么它会直接获取给定索引处的值,但是采用任何其他集合,这会非常慢并且会花费很多时间. 我尝试使用 foreach 循环(注释部分)来处理这个问题,这在使用 IEnumerable 时很有效,但是那部分不起作用,因为枚举器对于内部和外部循环都是通用的,因此这会生成所有 2 的集合- 元组,其中一些重复。 谁能给我一些建议,如何改进这段代码?

问题在于,Enumerable 旨在描述一个 class,您可以在其中迭代它(如流)。它不打算支持有效的随机访问(如数组)。

在您使用 Count() 的地方,您强制 Enumerable 将自身迭代到它的末尾,因此在 Stream 的情况下,这将等到整个流被读取。当然,Stream 可能不支持高效的直接访问,或者甚至在内存中缓冲其内容(记住 - 它只是承诺支持枚举) - 因此随后调用 ElementAt() 可能会强制它从头开始重新读取到指示的位置。

解决此问题的最佳方法是从 IEnumerable 切换到 IList。这意味着它确实支持随机访问;显然它仍然可能表现不佳,但这不是您的职能的责任。