Iterating an array with foreach backwards without using extension method - c#

After making a search at the Google, I found this discussion:
Possible to iterate backwards through a foreach?
But in the answers there is used extension method .Reverse(). With reverse, the list of objects, for ie. List of Strings, wtill be reversed first, and foreach doesn't reverse the list with my understoodment? If I got list "Cat", "Dog", and use .Reverse() -method, the list will be "Dog", "Cat", and foreach starts from the 0 element till the lenght-1 -element and that's what I'm not looking for. I would want to know, if there was any way to reverse foreach iteration order, to start from lenght-1 down to 0.

if there was any way to reverse foreach iteration order, to start from length-1 down to 0
Not for a List<T>. The implementation of GetEnumerator() returns an enumerator that enumerates from beginning to end - there's no way to override that.
With a custom collection, then you'd just have to use a different enumerator that could go backwards, but there's no way to override the implementation that List<T> uses.

The Reverse method will copy the list first:
public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source) {
if (source == null) throw Error.ArgumentNull("source");
return ReverseIterator<TSource>(source);
}
static IEnumerable<TSource> ReverseIterator<TSource>(IEnumerable<TSource> source) {
Buffer<TSource> buffer = new Buffer<TSource>(source);
for (int i = buffer.count - 1; i >= 0; i--) yield return buffer.items[i];
}
But you can do an extension method yourself:
public static IEnumerable<TSource> Backwards<TSource>(this IList<TSource> source) {
for (var i = source.Count - 1; i >= 0; --i)
yield return source[i];
}
And then use it like that:
foreach (var item in array.Backwards())
Console.WriteLine(item); // Or whatever else
Or, of course, you could just do the equivalent:
for (var i = array.Length - 1; i >= 0; --i)
Console.WriteLine(array[i]); // Or whatever else

You can implement an enumerator that iterates though a list backwards. That way you can use foreach without changing the original list or creating a copy of it.
public class ReverseEnumerator<T> : IEnumerator<T> {
private IList<T> _list;
private int _index;
private T _current;
public ReverseEnumerator(IList<T> list) {
_list = list;
Reset();
}
public IEnumerator<T> GetEnumerator() {
return this;
}
public T Current {
get {
if (_index < 0 && _index >= _list.Count) throw new InvalidOperationException("Enumeration has not started. Call MoveNext.");
return _current;
}
}
public void Dispose() { }
object IEnumerator.Current { get { return Current; } }
public bool MoveNext() {
bool ok = --_index >= 0;
if (ok) _current = _list[_index];
return ok;
}
public void Reset() {
_index = _list.Count;
}
}
Usage example:
int[] a = { 1, 2, 3, 4, 5 };
foreach (int x in new ReverseEnumerator<int>(a)) {
Console.WriteLine(x);
}

Related

Linq: ForEach item return the number of items needed to get n unique items starting at that item

Lets say I have a list of items:
[a,b,b,a,c,d,a,d,b,c]
and I need to know, for each item, how many items along do I have to traverse till I get n unique items, (and return eg -1, or otherwise indicate if that's not possible)
So here, if n = 4, I would return
[6,5,4,6,5,5,4,-1,-1,-1]
since
a,b,b,a,c,d contains 4 unique elements
b,b,a,c,d contains 4 unique elements
b,a,c,d contains 4 unique elements,
a,c,d,a,d,b contains 4 unique elements
etc.
I used
List.Select((x,i) => {
var range = List.Skip(i).GroupBy(y => y).Take(n);
if (range.Count() == n)
return range.SelectMany(y => y).Count();
return -1;
});
Although i'm pretty sure this is horribly non-performant.
To try to minimize overhead, I created a ListSpan extension class for managing subparts of a List - something like ArraySegment for List, but (loosely) modeled on Span:
public class ListSpan<T> : IEnumerable<T>, IEnumerable {
List<T> baseList;
int start;
int len;
public ListSpan(List<T> src, int start = 0, int? len = null) {
baseList = src;
this.start = start;
this.len = len ?? (baseList.Count - start);
if (this.start + this.len > baseList.Count)
throw new ArgumentException("start+len > Count for ListSpan");
}
public T this[int n]
{
get
{
return baseList[start + n];
}
set
{
baseList[start + n] = value;
}
}
public class ListSpanEnumerator<Te> : IEnumerator<Te>, IEnumerator {
int pos;
List<Te> baseList;
int end;
Te cur = default(Te);
public ListSpanEnumerator(ListSpan<Te> src) {
pos = src.start - 1;
baseList = src.baseList;
end = src.start + src.len;
}
public Te Current => cur;
object IEnumerator.Current => Current;
public bool MoveNext() {
if (++pos < end) {
cur = baseList[pos];
return true;
}
else {
cur = default(Te);
return false;
}
}
public void Reset() => pos = 0;
public void Dispose() { }
}
public IEnumerator<T> GetEnumerator() => new ListSpanEnumerator<T>(this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
public static class ListExt {
public static ListSpan<T> Slice<T>(this List<T> src, int start = 0, int? len = null) => new ListSpan<T>(src, start, len);
}
Then I created an extension method to return the distance (in Take terms) required to get n unique items from an IEnumerable:
public static class IEnumerableExt {
public static int DistanceToUnique<T>(this IEnumerable<T> src, int n, IEqualityComparer<T> cmp = null) {
var hs = new HashSet<T>(cmp ?? EqualityComparer<T>.Default);
var pos = 0;
using (var e = src.GetEnumerator()) {
while (e.MoveNext()) {
++pos;
hs.Add(e.Current);
if (hs.Count == n)
return pos;
}
}
return -1;
}
}
Now the answer is relatively straight forward:
var ans = Enumerable.Range(0, src.Count).Select(p => src.Slice(p).DistanceToUnique(n));
Basically I go through each position in the original (src) List and compute the distance to n unique values from that position using a ListSpan of the List starting at that position.
This still isn't terribly efficient in that I am creating a HashSet for every element in the original List and putting all the following elements in it, and traversing the elements up to k! times for a k element List. Still trying to come up with something really efficient.

What's the point of Enumerable.ElementAt<TSource>?

IEnumerable<T> exposes an enumerator, so the object can be enumerated. There is nothing about indexes exposed by this interface. IList<T> is about indexes, as it exposes the IndexOf method.
So what's the point of Enumerable.ElementAt? I just read the doc of this LINQ extension method:
Returns the element at a specified index in a sequence.
Well, yes, it's about a sequence, not just an IEnumerable. Reading the remarks:
If the type of source implements IList, that implementation is used
to obtain the element at the specified index. Otherwise, this method
obtains the specified element.
Okay, so if the concrete type implements something that inherits from IList<T> (which is an actual sequence), then it's the same as IndexOf(). If not, it iterates until the index is reached.
Here's a sample scenario:
// Some extension method exposed by a lib
// I know it's not a good piece of code, but let's say it's coded this way:
public static class EnumerableExtensions
{
// Returns true if all elements are ordered
public static bool IsEnumerableOrdered(this IEnumerable<int> value)
{
// Iterates over elements using an index
for (int i = 0; i < value.Count() - 1; i++)
{
if (value.ElementAt(i) > value.ElementAt(i + 1))
{
return false;
}
}
return true;
}
}
// Here's a collection that is enumerable, but doesn't always returns
// its objects in the same order
public class RandomAccessEnumerable<T> : IEnumerable<T>
{
private List<T> innerList;
private static Random rnd = new Random();
public RandomAccessEnumerable(IEnumerable<T> list)
{
innerList = list.ToList();
}
public IEnumerator<T> GetEnumerator()
{
var listCount = this.innerList.Count;
List<int> enumeratedIndexes = new List<int>();
for (int i = 0; i < listCount; i++)
{
int randomIndex = -1;
while (randomIndex < 0 || enumeratedIndexes.Contains(randomIndex))
{
randomIndex = rnd.Next(listCount);
}
enumeratedIndexes.Add(randomIndex);
yield return this.innerList[randomIndex];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
// Here's some test program
internal class Program
{
private static void Main()
{
var test0 = new List<int> { 0, 1, 2, 3 };
var test1 = new RandomAccessEnumerable<int>(test0);
Console.WriteLine("With List");
Console.WriteLine(test0.IsEnumerableOrdered()); // true
Console.WriteLine(test0.IsEnumerableOrdered()); // true
Console.WriteLine(test0.IsEnumerableOrdered()); // true
Console.WriteLine(test0.IsEnumerableOrdered()); // true
Console.WriteLine(test0.IsEnumerableOrdered()); // true
Console.WriteLine("With RandomAccessEnumerable");
Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false
Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false
Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false
Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false
Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false
Console.Read();
}
}
So, as RandomAccessEnumerable might return enumerated objects in a random order, you just can't rely on the simple IEnumerable<T> interface to assume your elements are indexed. So you don't want to use ElementAt for an IEnumerable.
In the above example, I think IsEnumerableOrdered should require a IList<T> parameter as it implies elements are a sequence. I actually can't find a scenario where the ElementAt method is useful, and not bug-prone.
There are many IEnumerable types like array or list. All IList types(which Array also implements) have an indexer which you can use to access elements at a specific index.
This will be used by Enumerable.ElementAt if the sequence can be casted to IList successfully. Otherwise it will be enumerated.
So it's just a convenient way to access elements at a given index for all kind of IEnumerable types.
This has the advantage that you can change the type later without needing to change all occurences of arr[index].
For what it's worth, here's the reflected(ILSpy) method to demonstrate what i've said:
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
return list[index];
}
if (index < 0)
{
throw Error.ArgumentOutOfRange("index");
}
TSource current;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (index == 0)
{
current = enumerator.Current;
return current;
}
index--;
}
throw Error.ArgumentOutOfRange("index");
}
return current;
}

Why is List<T>.Enumerator faster than my implementation?

I've found myself in a position where I have to roll my own dynamic array implementation, due to various large performance benefits (in my case). However, after creating an enumerator for my version, and comparing the efficiency with the one List uses, I'm a bit bewildered; the List one is aproximately 30-40% faster than my version, even though it's much more complex.
Here's the important part of the List enumerator implementation:
public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
{
private List<T> list;
private int index;
private int version;
private T current;
internal Enumerator(List<T> list)
{
this.list = list;
this.index = 0;
this.version = list._version;
this.current = default(T);
return;
}
public bool MoveNext()
{
List<T> list;
list = this.list;
if (this.version != list._version)
{
goto Label_004A;
}
if (this.index >= list._size)
{
goto Label_004A;
}
this.current = list._items[this.index];
this.index += 1;
return 1;
Label_004A:
return this.MoveNextRare();
}
public T Current
{
get { return this.current; }
}
}
And here's my very barebone version:
internal struct DynamicArrayEnumerator<T> : IEnumerator<T> where T : class
{
private readonly T[] internalArray;
private readonly int lastIndex;
private int currentIndex;
internal DynamicArrayEnumerator(DynamicArray<T> dynamicArray)
{
internalArray = dynamicArray.internalArray;
lastIndex = internalArray.Length - 1;
currentIndex = -1;
}
public T Current
{
get { return internalArray[currentIndex]; }
}
public bool MoveNext()
{
return (++currentIndex <= lastIndex);
}
}
I know this is micro-optimization, but I'm actually interested in understanding why the List enumerator is so much faster than mine. Any ideas? Thanks!
Edit:
As requested; the DynamicArray class (the relevant parts):
The enumerator is an inner class in this.
public struct DynamicArray<T> : IEnumerable<T> where T : class
{
private T[] internalArray;
private int itemCount;
internal T[] Data
{
get { return internalArray; }
}
public int Count
{
get { return itemCount; }
}
public DynamicArray(int count)
{
this.internalArray = new T[count];
this.itemCount = 0;
}
public IEnumerator<T> GetEnumerator()
{
return new DynamicArrayEnumerator<T>(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
As for how I'm testing:
List<BaseClass> list = new List<BaseClass>(1000000);
DynamicArray<BaseClass> dynamicArray = new DynamicArray<BaseClass>(1000000);
// Code for filling with data omitted.
int numberOfRuns = 0;
float p1Total = 0;
float p2Total = 0;
while (numberOfRuns < 100)
{
PerformanceAnalyzer p1 = new PerformanceAnalyzer(() =>
{
int u = 0;
foreach (BaseClass b in list)
{
if (b.B > 100) // Some trivial task
u++;
}
});
p1.ExecuteAndClock();
p1Total += p1.TotalElapsedTicks;
PerformanceAnalyzer p2 = new PerformanceAnalyzer(() =>
{
int u = 0;
foreach (BaseClass b in dynamicArray)
{
if (b.B > 100) // Some trivial task
u++;
}
});
p2.ExecuteAndClock();
p2Total += p2.TotalElapsedTicks;
numberOfRuns++;
}
Console.WriteLine("List enumeration: " + p1Total / totalRuns + "\n");
Console.WriteLine("Dynamic array enumeration: " + p2Total / totalRuns + "\n");
The PerformanceAnalyzer class basically starts a Stopwatch, execute the supplied Action delegate, and then stop the Stopwatch afterwards.
Edit 2 (Quick answer to Ryan Gates):
There's a few reasons why I would want to roll my own, most importantly I need a very fast RemoveAt(int index) method.
Since I don't have to worry about the order of the list elements in my particular case, I can avoid the .Net built-in list's way of doing it:
public void RemoveAt(int index)
{
T local;
if (index < this._size)
{
goto Label_000E;
}
ThrowHelper.ThrowArgumentOutOfRangeException();
Label_000E:
this._size -= 1;
if (index >= this._size)
{
goto Label_0042;
}
Array.Copy(this._items, index + 1, this._items, index, this._size - index);
Label_0042:
this._items[this._size] = default(T);
this._version += 1;
return;
}
And instead using something along the lines of:
public void RemoveAt(int index)
{
// overwrites the element at the specified index with the last element in the array and decreases the item count.
internalArray[index] = internalArray[itemCount];
itemCount--;
}
Potencially saving enormous amounts of time in my case, if say the first 1000 elements in a long list have to be removed by index.
Okay, aside from benchmarking problems, here's how you can make your DynamicArray class more like List<T>:
public DynamicArrayEnumerator<T> GetEnumerator()
{
return new DynamicArrayEnumerator<T>(this);
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
Now, code which knows it's working with a dynamic array can iterate with a DynamicArrayEnumerator<T> without any boxing, and without virtual dispatch. This is exactly what List<T> does. The compiler notices when a type implements the pattern in a custom manner, and will use the types involved instead of the interfaces.
With your current code, you're getting no benefit from creating a struct - because you're boxing it in GetEnumerator().
Try the above change and fix the benchmark to work for longer. I'd expect to see a big difference.

Does .NET have a built in IEnumerable for multiple collections?

I need an easy way to iterate over multiple collections without actually merging them, and I couldn't find anything built into .NET that looks like it does that. It feels like this should be a somewhat common situation. I don't want to reinvent the wheel. Is there anything built in that does something like this:
public class MultiCollectionEnumerable<T> : IEnumerable<T>
{
private MultiCollectionEnumerator<T> enumerator;
public MultiCollectionEnumerable(params IEnumerable<T>[] collections)
{
enumerator = new MultiCollectionEnumerator<T>(collections);
}
public IEnumerator<T> GetEnumerator()
{
enumerator.Reset();
return enumerator;
}
IEnumerator IEnumerable.GetEnumerator()
{
enumerator.Reset();
return enumerator;
}
private class MultiCollectionEnumerator<T> : IEnumerator<T>
{
private IEnumerable<T>[] collections;
private int currentIndex;
private IEnumerator<T> currentEnumerator;
public MultiCollectionEnumerator(IEnumerable<T>[] collections)
{
this.collections = collections;
this.currentIndex = -1;
}
public T Current
{
get
{
if (currentEnumerator != null)
return currentEnumerator.Current;
else
return default(T);
}
}
public void Dispose()
{
if (currentEnumerator != null)
currentEnumerator.Dispose();
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public bool MoveNext()
{
if (currentIndex >= collections.Length)
return false;
if (currentIndex < 0)
{
currentIndex = 0;
if (collections.Length > 0)
currentEnumerator = collections[0].GetEnumerator();
else
return false;
}
while (!currentEnumerator.MoveNext())
{
currentEnumerator.Dispose();
currentEnumerator = null;
currentIndex++;
if (currentIndex >= collections.Length)
return false;
currentEnumerator = collections[currentIndex].GetEnumerator();
}
return true;
}
public void Reset()
{
if (currentEnumerator != null)
{
currentEnumerator.Dispose();
currentEnumerator = null;
}
this.currentIndex = -1;
}
}
}
Try the SelectMany extension method added in 3.5.
IEnumerable<IEnumerable<int>> e = ...;
foreach ( int cur in e.SelectMany(x => x)) {
Console.WriteLine(cur);
}
The code SelectMany(x => x) has the effect of flattening a collection of collections into a single collection. This is done in a lazy fashion and allows for straight forward processing as shown above.
If you only have C# 2.0 available, you can use an iterator to achieve the same results.
public static IEnumerable<T> Flatten<T>(IEnumerable<IEnumerable<T>> enumerable) {
foreach ( var inner in enumerable ) {
foreach ( var value in inner ) {
yield return value;
}
}
}
Just use the Enumerable.Concat() extension method to "concatenate" two IEnumerables. Don't worry, it doesn't actually copy them into a single array (as you might infer from the name), it simply allows you to enumerate over them all as if they were one IEnumerable.
If you have more than two then Enumerable.SelectMany() would be better.

Move item up in IEnumerable

I have a need to move an item in an IEnumerable<> up, that is move one item above another. What is the simplest way to do this?
A similar question was asked here but I don't have a generic list only an IEnumerable<>: Generic List - moving an item within the list
As #Brian commented the question is a little unclear as to what move an item in an IEnumerable<> up means.
If you want to reorder an IEnumerable for a single item then the code below should might be what you are looking for.
public static IEnumerable<T> MoveUp<T>(this IEnumerable<T> enumerable, int itemIndex)
{
int i = 0;
IEnumerator<T> enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
i++;
if (itemIndex.Equals(i))
{
T previous = enumerator.Current;
if (enumerator.MoveNext())
{
yield return enumerator.Current;
}
yield return previous;
break;
}
yield return enumerator.Current;
}
while (enumerator.MoveNext())
{
yield return enumerator.Current;
}
}
You can't. IEnumerable is only to iterate through some items, not for editing a list of items
You can use the ToList() extension method and use the answer from the question you referenced. e.g.
var list = enumerable.ToList();
//do stuff from other answer, and then convert back to enumerable if you want
var reorderedEnumerable = list.AsEnumerable();
I didn't find anything that would do what you want with IEnumerable<T>. Having developed similar stuff in the past for specific types of collections, list, arrays, etc, I felt it was time to take a better look at it. So I took a couple of minutes to write a generic version that could be applied to any IEnumerable<T>.
I did some basic testing and parameter checking but by no means consider them compreensive.
Given that disclaimer, let's get to the code:
static class Enumerable {
public static IEnumerable<T> MoveDown<T>(this IEnumerable<T> source, int index) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
if (index == array.Length - 1) {
return source;
}
return Swap<T>(array, index, index + 1);
}
public static IEnumerable<T> MoveDown<T>(this IEnumerable<T> source, T item) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
int index = Array.FindIndex(array, i => i.Equals(item));
if (index == -1) {
throw new InvalidOperationException();
}
if (index == array.Length - 1) {
return source;
}
return Swap<T>(array, index, index + 1);
}
public static IEnumerable<T> MoveUp<T>(this IEnumerable<T> source, int index) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
if (index == 0) {
return source;
}
return Swap<T>(array, index - 1, index);
}
public static IEnumerable<T> MoveUp<T>(this IEnumerable<T> source, T item) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
int index = Array.FindIndex(array, i => i.Equals(item));
if (index == -1) {
throw new InvalidOperationException();
}
if (index == 0) {
return source;
}
return Swap<T>(array, index - 1, index);
}
public static IEnumerable<T> Swap<T>(this IEnumerable<T> source, int firstIndex, int secondIndex) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
return Swap<T>(array, firstIndex, secondIndex);
}
private static IEnumerable<T> Swap<T>(T[] array, int firstIndex, int secondIndex) {
if (firstIndex < 0 || firstIndex >= array.Length) {
throw new ArgumentOutOfRangeException("firstIndex");
}
if (secondIndex < 0 || secondIndex >= array.Length) {
throw new ArgumentOutOfRangeException("secondIndex");
}
T tmp = array[firstIndex];
array[firstIndex] = array[secondIndex];
array[secondIndex] = tmp;
return array;
}
public static IEnumerable<T> Swap<T>(this IEnumerable<T> source, T firstItem, T secondItem) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
int firstIndex = Array.FindIndex(array, i => i.Equals(firstItem));
int secondIndex = Array.FindIndex(array, i => i.Equals(secondItem));
return Swap(array, firstIndex, secondIndex);
}
}
As you can see, MoveUp and MoveDown are basically Swap operations. With MoveUp you swap positions with the previous element and with MoveDown you swap positions with the next element.
Of course, that does not apply for moving up the first element or moving down the last element.
Running a quick test with the code below...
class Program {
static void Main(string[] args) {
int[] a = { 0, 2, 1, 3, 4 };
string[] z = { "Zero", "Two", "One", "Three", "Four" };
IEnumerable<int> b = Enumerable.Swap(a, 1, 2);
WriteAll(b);
IEnumerable<int> c = Enumerable.MoveDown(a, 1);
WriteAll(c);
IEnumerable<int> d = Enumerable.MoveUp(a, 2);
WriteAll(d);
IEnumerable<int> f = Enumerable.MoveUp(a, 0);
WriteAll(f);
IEnumerable<int> g = Enumerable.MoveDown(a, 4);
WriteAll(g);
IEnumerable<string> h = Enumerable.Swap(z, "Two", "One");
WriteAll(h);
var i = z.MoveDown("Two");
WriteAll(i);
var j = z.MoveUp("One");
WriteAll(j);
Console.WriteLine("Press any key to continue...");
Console.Read();
}
private static void WriteAll<T>(IEnumerable<T> b) {
foreach (var item in b) {
Console.WriteLine(item);
}
}
... it looks like everything is working well.
I hope it serves at least as a starting point for you.
I like this approach
/// <summary>
/// Extension methods for <see cref="System.Collections.Generic.List{T}"/>
/// </summary>
public static class ListExtensions
{
public static void MoveForward<T>(this List<T> list, Predicate<T> itemSelector, bool isLastToBeginning)
{
Ensure.ArgumentNotNull(list, "list");
Ensure.ArgumentNotNull(itemSelector, "itemSelector");
var currentIndex = list.FindIndex(itemSelector);
// Copy the current item
var item = list[currentIndex];
bool isLast = list.Count - 1 == currentIndex;
if (isLastToBeginning && isLast)
{
// Remove the item
list.RemoveAt(currentIndex);
// add the item to the beginning
list.Insert(0, item);
}
else if (!isLast)
{
// Remove the item
list.RemoveAt(currentIndex);
// add the item at next index
list.Insert(currentIndex + 1, item);
}
}
public static void MoveBack<T>(this List<T> list, Predicate<T> itemSelector, bool isFirstToEnd)
{
Ensure.ArgumentNotNull(list, "list");
Ensure.ArgumentNotNull(itemSelector, "itemSelector");
var currentIndex = list.FindIndex(itemSelector);
// Copy the current item
var item = list[currentIndex];
bool isFirst = 0 == currentIndex;
if (isFirstToEnd && isFirst)
{
// Remove the item
list.RemoveAt(currentIndex);
// add the item to the end
list.Add(item);
}
else if (!isFirstToEnd)
{
// Remove the item
list.RemoveAt(currentIndex);
// add the item to previous index
list.Insert(currentIndex - 1, item);
}
}
}

Categories