2016-09-16 19 views
1

IEnumerable<T>のコピーを作成したいのですが、特定のインデックスにある1つの商品が所定の値に置き換えられました。IEnumerableをコピーして商品を交換してください

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

しかし、理解することは、おそらく簡単ながら、の1がすでにによって撮影した項目をスキップする2回の反復子を作成するために、「非効率的」と思われる:

は、私が何をしたいんどの次のメソッドを定義し最初のイテレータ。

これを定義するより良い方法はありますか?

答えて

2

方法について:

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

まあ、公正を。この答えは私よりもイーグルです:) – tym32167

+0

@ tym32167まあ、とにかくあなたの答えをアップアップしました。 ;) –

2

効率的わからが、あなたはこれを試しているわけではありませんか?

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

お互いに10秒以内に2つの同じ答えがあります。 :) –

+0

@MatthewWatson:D nice – tym32167

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

これは 'foreach'を使って同じことをするよりもどうですか?私。 'int itemIndex = 0; foreach(ソースのvar値) { yield returnIndex ++ == index?アイテム:値; } '。 – svick

+0

@svick十分に公正、それはほぼ同じでしょう。私は私の頭の中で、もっと微妙な例に慣れていると思います。しかし、後ろ向きでは、これはかなりシンプルです –

関連する問題