如何只通过一次交换来交换枚举项?

Ken*_*Kin 0 c# linq ienumerable enumeration

我正在尝试交换一个特定项目的顺序IEnumerable.

鉴于IEnumerable<int> a;以下要素:

1,2,3,4,5

我想要做的是写一个交换迭代器,结果a.Exchange(1, 2)是:

1,3,2,4,5

但是我不希望这个简单的目的可以多次迭代枚举.到目前为止我所拥有的是:

public static IEnumerable<T> Exchange<T>(
    this IEnumerable<T> source, int index1, int index2) {
    var i=0;

    foreach(var y in source) {
        if(index1==i) {
            var j=0;

            foreach(var x in source) {
                if(index2==j) {
                    yield return x;
                    break;
                }

                ++j;
            }
        }
        else {
            if(index2==i) {
                var j=0;

                foreach(var x in source) {
                    if(index1==j) {
                        yield return x;
                        break;
                    }

                    ++j;
                }
            }
            else {
                yield return y;
            }
        }

        ++i;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个假设,index1并且index2不会超过可枚举的元素.在大多数情况下,代码完成了交换工作(排序),但它确实迭代了不止一次.注意index1index2可能不是真正的指数source,它们将是MthNth当枚举发生的元素.

ToArray或者ToList也可能增加迭代次数.

Eri*_*ert 8

WOLOG认为index1小于index2.

建立自己的普查员; 不要用foreach.

对于最多的元素index1,正常迭代并产生每个元素.

然后当你点击时index1,分配一个足够大的数组来保持index1通过之间的元素index2- 也就是说,包括index1th元素,但不包括index2th元素.

使用枚举器将元素读入该数组.

现在读取第index2th个元素并将其生成.

您的枚举器现在设置为超出一个index2.

现在产生index1 th元素之外的数组中的所有内容.

然后产生第index1th个元素.

然后通常产生其余元素.

完成后别忘了打电话Dispose给调查员.

  • @Sphinxxx:看起来我们有两个不同的实现,一个使用foreach,一个使用显式枚举器.我认为两者都很容易阅读,所以事实证明这是一个品味问题. (2认同)