The easiest way is something like this:
public static IEnumerable<T> Exchange<T>( this IEnumerable<T> source, int index1, int index2) { return source.Select((x, i) => new { x, i }) .OrderBy(p => pi == index1 ? index2 : pi == index2 ? index1 : pi) .Select(p => px); } new[] { 1, 2, 3, 4, 5 }.Exchange(1, 2);
To do this without OrderBy , I think it would look something like this:
public static IEnumerable<T> Exchange<T>( this IEnumerable<T> source, int index1, int index2) { if (index1 > index2) { int x = index1; index1 = index2; index2 = x; } int index = 0; List<T> itemsBetweenIndexes = new List<T>(); bool betweenIndexes = false; T temp = default(T); foreach(var item in source) { if (!betweenIndexes) { if (index == index1) { temp = item; betweenIndexes = true; } else { yield return item; } } else { if (index == index2) { betweenIndexes = false; yield return item; foreach(var x in itemsBetweenIndexes) { yield return x; } itemsBetweenIndexes.Clear(); yield return temp; } else { itemsBetweenIndexes.Add(item); } } index++; } }
This initially happens by searching for an element in index1 giving each element until it finds it. After that, it starts adding items to the internal queue until it finds index2 . At this point, it returns an element in index2 , followed by each element in the queue, in order, followed by the element index1 . He then returns to searching index1 (which he will not find) until he reaches the end of the list.
source share