复制IEnumerable,替换项目

时间:2016-09-16 09:58:51

标签: c# iterator ienumerable yield-return

我想制作IEnumerable<T>的副本,其中给定索引处的单个项目已被给定值替换。

我定义了以下方法,它可以满足我的需求:

public static IEnumerable<T> ReplaceAt<T>(this IEnumerable<T> source, T item, int index)
{
    foreach (T before in source.Take(index))
    {
        yield return before;
    }

    yield return item;

    foreach (T after in source.Skip(index + 1))
    {
        yield return after;
    }
}

然而,尽管可能很容易理解,但似乎效率低下。创建两个迭代器,其中一个迭代器跳过第一个迭代器已经占用的项目。

有没有更好的方法来定义它?

3 个答案:

答案 0 :(得分:2)

怎么样:

public static IEnumerable<T> ReplaceAt<T>(this IEnumerable<T> source, T item, int index)
{
    return source.Select((value, i) => index == i ? item : value);
} 

答案 1 :(得分:2)

不确定效率,但你试过这个吗?

public static IEnumerable<T> ReplaceAt<T>(this IEnumerable<T> source, T item, int index)
{
    return source.Select((x, i) => i == index ? item : x);
}   

答案 2 :(得分:1)

如果您想发疯,可以手动展开foreach

public static IEnumerable<T> ReplaceAt<T>(this IEnumerable<T> source, T item, int index)
{
    int itemIndex = 0;
    using(var iter = source.GetEnumerator())
    {
        while(iter.MoveNext())
        {
            yield return itemIndex++ == index ? item : iter.Current;
        }
    }
}