如何只进行一次交互就交换枚举项? [英] How to exchange the items of enumeration by interating only once?

查看:77
本文介绍了如何只进行一次交互就交换枚举项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to exchange the ordering of particular items of an IEnumerable.

给出元素的IEnumerable<int> a;:

1、2、3、4、5

1, 2, 3, 4, 5

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

and what I want to do is write a exchange iterator which resulting a.Exchange(1, 2) in:

1、3、2、4、5

1, 3, 2, 4, 5

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

But I don't want the enumerable be iterated more than once with this simple purpose. What I have so far is:

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

这里假设index1index2不会超出可枚举的元素.该代码在大多数情况下完成了交换(排序)的工作,但是它反复进行了多次.注意index1index2可能不是source的实数索引,当枚举发生时,它们将是MthNth元素.

Here's a assumption that index1 and index2 wouldn't exceed the elements of the enumerable. The code done the work of exchange(the ordering) in most cases, but it does iterate more than once. Note index1 and index2 might not be the real indices of source, they would be the Mth and Nth element when the enumeration occurs.

ToArrayToList也可能会增加迭代次数.

ToArray or ToList may also increase the times of iteration.

推荐答案

WOLOG假定index1小于index2.

WOLOG assume that index1 is less than index2.

创建自己的枚举器;不要使用foreach.

Make your own enumerator; don't use foreach.

对于不超过index1的元素,请正常进行迭代并生成每个元素.

For elements up to index1, iterate normally and yield each.

然后,当您按下index1时,分配一个足够大的数组以容纳index1index2之间的元素-也就是说,包括第index1个元素,但不包括第index2个元素.

Then when you hit index1, allocate an array big enough to hold the elements between index1 through index2 -- that is, including the index1th element, but not the index2th element.

使用枚举器将元素读取到该数组中.

Read the elements into that array using your enumerator.

现在读取第index2个元素并产生它.

Now read the index2th element and yield it.

您的枚举数现在已设置为index2以外的一种.

Your enumerator is now set to one beyond index2.

现在产生数组第c3个元素之外的所有内容.

Now yield everything in the array except the index1th element.

然后产生第index1个元素.

然后正常产生其余元素.

Then yield the rest of the elements normally.

完成后,别忘了在枚举器上调用Dispose.

Don't forget to call Dispose on the enumerator when you're done.

这篇关于如何只进行一次交互就交换枚举项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆