foreach with index [duplicate] - c#

This question already has answers here:
How do you get the index of the current iteration of a foreach loop?
(35 answers)
Closed 9 years ago.
Is there a C# equivalent of Python's enumerate() and Ruby's each_with_index?

I keep this extension method around for this:
public static void Each<T>(this IEnumerable<T> ie, Action<T, int> action)
{
var i = 0;
foreach (var e in ie) action(e, i++);
}
And use it like so:
var strings = new List<string>();
strings.Each((str, n) =>
{
// hooray
});
Or to allow for break-like behaviour:
public static bool Each<T>(this IEnumerable<T> ie, Func<T, int, bool> action)
{
int i = 0;
foreach (T e in ie) if (!action(e, i++)) return false;
return true;
}
var strings = new List<string>() { "a", "b", "c" };
bool iteratedAll = strings.Each ((str, n)) =>
{
if (str == "b") return false;
return true;
});

You can do the following
foreach (var it in someCollection.Select((x, i) => new { Value = x, Index = i }) )
{
if (it.Index > SomeNumber) //
}
This will create an anonymous type value for every entry in the collection. It will have two properties
Value: with the original value in the collection
Index: with the index within the collection

The C# foreach doesn't have a built in index. You'll need to add an integer outside the foreach loop and increment it each time.
int i = -1;
foreach (Widget w in widgets)
{
i++;
// do something
}
Alternatively, you could use a standard for loop as follows:
for (int i = 0; i < widgets.Length; i++)
{
w = widgets[i];
// do something
}

I like being able to use foreach, so I made an extension method and a structure:
public struct EnumeratedInstance<T>
{
public long cnt;
public T item;
}
public static IEnumerable<EnumeratedInstance<T>> Enumerate<T>(this IEnumerable<T> collection)
{
long counter = 0;
foreach (var item in collection)
{
yield return new EnumeratedInstance<T>
{
cnt = counter,
item = item
};
counter++;
}
}
and an example use:
foreach (var ii in new string[] { "a", "b", "c" }.Enumerate())
{
Console.WriteLine(ii.item + ii.cnt);
}
One nice thing is that if you are used to the Python syntax, you can still use it:
foreach (var ii in Enumerate(new string[] { "a", "b", "c" }))

Aside from the LINQ answers already given, I have a "SmartEnumerable" class which allows you to get the index and the "first/last"-ness. It's a bit ugly in terms of syntax, but you may find it useful.
We can probably improve the type inference using a static method in a nongeneric type, and implicit typing will help too.

My solution involves a simple Pair class I created for general utility, and which is operationally essentially the same as the framework class KeyValuePair. Then I created a couple extension functions for IEnumerable called Ordinate (from the set theory term "ordinal").
These functions will return for each item a Pair object containing the index, and the item itself.
public static IEnumerable<Pair<Int32, X>> Ordinate<X>(this IEnumerable<X> lhs)
{
return lhs.Ordinate(0);
}
public static IEnumerable<Pair<Int32, X>> Ordinate<X>(this IEnumerable<X> lhs, Int32 initial)
{
Int32 index = initial - 1;
return lhs.Select(x => new Pair<Int32, X>(++index, x));
}

No, there is not.
As other people have shown, there are ways to simulate Ruby's behavior. But it is possible to have a type that implements IEnumerable that does not expose an index.

This is your collection
var values = new[] {6, 2, 8, 45, 9, 3, 0};
Make a range of indexes for this collection
var indexes = Enumerable.Range(0, values.Length).ToList();
Use the range to iterate with index
indexes.ForEach(i => values[i] += i);
indexes.ForEach(i => Console.Write("[{0}] = {1}", i, values[i]));

I just figured out interesting solution:
public class DepthAware<T> : IEnumerable<T>
{
private readonly IEnumerable<T> source;
public DepthAware(IEnumerable<T> source)
{
this.source = source;
this.Depth = 0;
}
public int Depth { get; private set; }
private IEnumerable<T> GetItems()
{
foreach (var item in source)
{
yield return item;
++this.Depth;
}
}
public IEnumerator<T> GetEnumerator()
{
return GetItems().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
// Generic type leverage and extension invoking
public static class DepthAware
{
public static DepthAware<T> AsDepthAware<T>(this IEnumerable<T> source)
{
return new DepthAware<T>(source);
}
public static DepthAware<T> New<T>(IEnumerable<T> source)
{
return new DepthAware<T>(source);
}
}
Usage:
var chars = new[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'}.AsDepthAware();
foreach (var item in chars)
{
Console.WriteLine("Char: {0}, depth: {1}", item, chars.Depth);
}

It depends on the class you are using.
Dictionary<(Of <(TKey, TValue>)>) Class For Example Support This
The Dictionary<(Of <(TKey, TValue>)>) generic class provides a mapping from a set of keys to a set of values.
For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair<(Of <(TKey, TValue>)>) structure representing a value and its key. The order in which the items are returned is undefined.
foreach (KeyValuePair kvp in myDictionary) {...}

Related

Extension Method for List to compute WhereNot

I have one requirement to implement the extension method for List to find out the WhereNot. I am not suppose to use any existing Linq extension method like where etc.
For Example
IEnumerable<int> list = new List<int> {1,2,3,4,5,6};
var whereNotListInt = list.WhereNot((num) => num > 3));
foreach(int i in whereNotListInt)
{
Console.WriteLine(i);
}
Output:-
1
2
3
IEnumerable<string> list = new List<string> {"Cat", "Dog"};
var whereNotListStr = list.WhereNot((str) => str.StartsWith("D")));
foreach(string str in whereNotListStr )
{
Console.WriteLine(str);
}
Output: Cat
I tried below solution, but not able to figure out how to call the function.
public static class Utility
{
public static IEnumerable<T> WhereNot<T>(this IEnumerable<T> list, Func<T, bool> func)
{
foreach (var item in list)
{
yield return func(item);
}
}
}
Since you only want to return items for which the condition is not true, only return each item when func() returns false on that item.
public static class Utility
{
public static IEnumerable<T> WhereNot<T>(this IEnumerable<T> list, Func<T, bool> func)
{
foreach (var item in list)
{
if (!func(item))
yield return item;
}
}
}

Multiple IEnumerable iterations [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I want to pass IEnumerable while having IEnumerable of IEnumerable.
Use case
class A
{
IEnumerable<int> _ints;
public A(IEnumerable<int> ints) => _ints = ints;
public B CreateB() => new B(_ints);
}
class B
{
public B(IEnumerable<int> ints)
{
foreach (int i in ints) { Console.WriteLine(i); }
}
}
class Program {
static void Main() {
var a = new A();
a.CreateB(); // Sequence 1
a.CreateB(); // Sequence 2
}
}
There are 2 solutions.
1: Special IEnumerable which returns different sequence from GetEnumerator.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
internal class MultiEnumerable<T> : IEnumerable<T>
{
private IEnumerable<IEnumerable<T>> _source;
public MultiEnumerable(IEnumerable<IEnumerable<T>> source)
{
_source = source;
}
public IEnumerator<T> GetEnumerator()
{
var current = _source.Take(1).First();
_source = _source.Skip(1);
return current.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public static class MultiEnumerableExtension
{
public static IEnumerable<T> AsMultiEnumerable<T>(this IEnumerable<IEnumerable<T>> source)
{
return new MultiEnumerable<T>(source);
}
}
static class Program
{
public static void Main()
{
IEnumerable<IEnumerable<int>> arrayOfArray =
new[]
{
new[] {1}, new[] {2}, new[] {3}, new[] {4}
};
IEnumerable<int> arrayOfArrayAsEnumerable = arrayOfArray.AsMultiEnumerable();
for (int x = 0; x < 4; x++)
{
Console.WriteLine("---");
foreach (var i in arrayOfArrayAsEnumerable)
{
Console.WriteLine(i);
}
}
}
}
}
Solution 2: Use method which takes IEnumerable of IEnumerable and returns first sequence while advancing:
class Utils{
public static IEnumerable<T> GetFirstAndAdvance<T>(ref IEnumerable<IEnumerable<T>> source)
{
var res = source.First();
source = source.Skip(1);
return res;
}
}
class A
{
IEnumerable<IEnumerable<int>> _ints;
public A(IEnumerable<IEnumerable<int>> ints) => _ints = ints;
public B CreateB() => new B(Utils.GetFirstAndAdvance(ref _ints));
}
There are a bunch of issues with your implementation of MultiEnumerable<T>.
To start with, these two lines are causing multiple iterations of the outer enumerable:
var current = _source.Take(1).First();
_source = _source.Skip(1);
Each time you go back and call GetEnumerator() you're running through the outer enumerable again to get back to the next inner enumerable.
Next, you're expecting the caller to know how many times to call GetEnumerator(). You've done this in your code with the for (int x = 0; x < 4; x++) where you know you should iterate the code 4 times. Had you iterated 5 times you would have gotten a n InvalidOperationException exception telling you that the "Sequence contains no elements".
These problems would have gone away had you written your test code using standard C# foreach loops.
foreach (var array in arrayOfArray)
{
Console.WriteLine("---");
foreach (var i in array)
{
Console.WriteLine(i);
}
}
Which really then leads to a way of writing a better MultiEnumerable<T>
internal class MultiEnumerable<T> : IEnumerable<T>
{
private IEnumerable<IEnumerable<T>> _source;
public MultiEnumerable(IEnumerable<IEnumerable<T>> source)
{
_source = source;
}
private IEnumerable<T> Iterate()
{
foreach (var inner in _source)
{
foreach (var element in inner)
{
yield return element;
}
}
}
public IEnumerator<T> GetEnumerator() => this.Iterate().GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}
Or even more simply, ignore the helper class, and just implement like this:
public static IEnumerable<T> AsMultiEnumerable<T>(this IEnumerable<IEnumerable<T>> source)
{
foreach (var inner in source)
{
foreach (var element in inner)
{
yield return element;
}
}
}
Naturally, your test code becomes simpler in both implementations:
IEnumerable<int> arrayOfArrayAsEnumerable = arrayOfArray.AsMultiEnumerable();
foreach (var i in arrayOfArrayAsEnumerable)
{
Console.WriteLine(i);
}
However, this code now just re-implements SelectMany. You could have just written your code like this:
foreach (var i in arrayOfArray.SelectMany(x => x))
{
Console.WriteLine(i);
}
It's better to use a well-known, standard operator as the code should then be easier to read and reason about.
You can use LINQ's SelectMany method.
IEnumerable<IEnumerable<int>> arrayOfArray = new[]
{
new[] {1}, new[] {2}, new[] {3}, new[] {4}
};
var allElements = arrayOfArray.SelectMany(element => element);
foreach (var element in allElements)
{
Console.WriteLine(element);
}
// Output:
// 1
// 2
// 3
// 4

What is the name of this sorting algorithm in c#

public static int[] Sort(int[] ints)
{
var dictionary = new IndexedDictionary<int, int>();
foreach (var i in ints)
{
dictionary.Add(i, i);
}
for (int i = 0; i <= ints.Length - 1; i++)
{
var indexValue = dictionary[i].Key;
dictionary[indexValue - 1].Value = indexValue;
}
return dictionary.Values();
}
Is it a bucket sort? I've seen a few bucket sorts and they look more complicated than this. Also please ignore the IndexedDictionary class - its a custom class to allow for getting values by index.
Edit: CompuChip - if you want to see the IndexedDictionary:
public class IndexedDictionary<T, TY>
{
public class DicObject<T, Y>
{
public T Key { get; set; }
public Y Value { get; set; }
}
private HashSet<DicObject<T, TY>> list = new HashSet<DicObject<T, TY>>();
public void Add(T o, TY u)
{
list.Add(new DicObject<T, TY>{Key = o, Value = u});
}
public DicObject<T, TY> this[int i] {
get{return list.ElementAt(i);}
}
public T[] Keys()
{
return list.Select(x => x.Key).ToArray();
}
public TY[] Values()
{
return list.Select(x => x.Value).ToArray();
}
}
Its not the crux at all.
That is a form of pigeon hole sorting, but it's limited to only being capable of sorting collections with unique values ranging from 1 and up without gaps. (If you for example try to sort the array {4,3,2} it will crash.)
So, for any collection that it works for, it does the same thing as:
public static int[] Sort(int[] ints) {
return Enumerable.Range(1, ints.Length).ToArray();
}
The IndexedDictionary is only a complicated and slow way to iterate through the items in an arbitrary order and put each value in place according to the same arbitrary order so that they end up being sorted. You can do the same thing much simpler and faster with a regular array:
public static int[] Sort(int[] ints) {
int[] result = new int[ints.Length];
foreach (int value in ints) {
result[value - 1] = value;
}
return result;
}
For an implementation that works with collections that doesn't have to have a lowest value of 1 and be continuous, you would create an array that spans from the lowest to the highest value and put the values in it, then collect them in order:
public static int[] Sort(int[] ints) {
int min = ints.Min();
int max = ints.Max();
int?[] pigeonHoles = new int?[max - min + 1];
foreach (int value in ints) {
pigeonHoles[value - min] = value;
}
int[] result = new int[ints.Length];
int index = 0;
foreach (int? value in pigeonHoles) {
if (value.HasValue) {
result[index++] = value.Value;
}
}
return result;
}
I'm not sure how we can ignore the IndexedDictionary as it seems to be the crux of your algorithm, but assuming it works like a standard dictionary I would think this is basically an insert sort - you put all your values into a dictionary which inserts it in the right place to keep its keys sorted and in the end you just extract all the values which are in the proper order by then. However, all the hard work is invisible because it is inside the Dictionary class.
A similar solution in terms of standard classes would be something like
public static IEnumerable<int> Sort(int[] ints)
{
var dictionary = new Dictionary<int, bool>();
foreach (var i in ints)
{
dictionary.Add(i, false);
}
return dictionary.Keys;
}
(although this does not deal with numbers occurring more than once).

Type to track the position of a list using IEnumerable

I’m trying to develop a type to track the current iteration position with a list.
I ideally want to used it with a foreach loop using the IEnumerable interface but the interface has no start/stop events or method to hooking to reset the count.
Currently I have created a GetNext( ) method which return the next value in the list and increments a count by 1.
Does anyone know I can achieve the same functionality using IEnumerable so I can use the type with a foreach loop?
So for example; imagine a list contains 10 items. One method could iterate an instance of the type to position 4 then method two would iterate the same instance starting at position 5 to 6 then method 3 would iterate the remainng from position 7 to 10 – so the type instance tracks the current position.
Any ideas are greatly appreciated (code shown below) . Thanks
public sealed class PositionTracker<T> : IEnumerable
{
private readonly object _syncLock = new object();
private readonly IList<T> _list = new List<T>();
private int _current;
public PositionTracker(IList<T> list)
{
_list = list;
}
public T GetCurrent()
{
lock (_syncLock)
{
return _list[_current];
}
}
public T GetNext()
{
lock (_syncLock)
{
T t = GetCurrent();
if (_current < _list.Count - 1)
{
_current++;
}
return t;
}
}
public IEnumerator<T> GetEnumerator()
{
lock (_syncLock)
{
return _list.GetEnumerator();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Reset()
{
lock (_syncLock)
{
_current = 0;
}
}
public int Count
{
get
{
lock (_syncLock)
{
return _list.Count;
}
}
}
}
[TestFixture]
public class PositionTrackerTests
{
[Test]
public void Position_CurrentPosition_Test()
{
List<string> list = new List<string>(new string[] { "A", "B", "C", "D" });
PositionTracker<string> positionTracker = new PositionTracker<string>(list);
Assert.IsTrue(positionTracker.GetNext().Equals("A"));
Assert.IsTrue(positionTracker.GetNext().Equals("B"));
Assert.IsTrue(positionTracker.GetNext().Equals("C"));
Assert.IsTrue(positionTracker.GetNext().Equals("D"));
}
}
Have a look at yield keyword. Especially this link of Chapter 6 of the Book 'C# in Depth' By Jon Skeet
P.S. I hope you are doing it in C#.NET 2.0+
Check this link: foreach with generic List, detecting first iteration when using value type
There is a link to a SmartEnumerable class by Jon Skeet. It is basically a wrapper for IEnumerable, which gives you a public SmartEnumerable<string>.Entry class which contains the item's index.
Also, nothing stops you from doing this:
public class MyClass
{
private List<String> list = new List<String>() { "1", "2", "3", "4", "5" }
public IEnumerable<String> GetItems(int from, int to)
{
for (int i=from; i<to; i++)
yield return list[i];
}
}
You can achieve most of this with an extension method, and overloads of Enumerable.Select and Where.
Both Select and Where have overloads where the delegate is passed both the item and its index:
var input = new[]{'a','b','c','d'};
var indexed = input.Select((v,i) => new { Value = v, Index = i });
foreach (var v in indexed) {
Console.WriteLine("Index #{0} is '{1}'", v.Index, v.Value);
}
To trigger delegates before the first and after the last items (but only if there is at least one item):
public static IEnumerable<T> StartAndEnd<T>(this IEnumerable<T> input,
Action onFirst,
Action onLast) {
var e = input.GetEnumerator();
if (!e.MoveNext()) { yield break; }
onFirst();
do {
yield return e.Current;
} while (e.MoveNext());
onLast();
}
and then use it as:
var input = new[]{'a','b','c','d'};
var indexed = input.StartAndEnd(() => { Console.WriteLine("First!");},
() => { Console.WriteLine("Last!");})
.Select((v,i) => new { Value = v, Index = i });
foreach (var v in indexed) {
Console.WriteLine("Index #{0} is '{1}'", v.Index, v.Value);
}
which gives the result:
First!
Index #0 is 'a'
Index #1 is 'b'
Index #2 is 'c'
Index #3 is 'd'
Last!
The delegates could set a local (by forming a closure) which is checked in a loop.
A more sophisticated version could call the onLast delegate before the last element of the sequence, but this would require buffering an element of the sequence to detect end before yielding that element.

Sorting an IList in C#

So I came across an interesting problem today. We have a WCF web service that returns an IList. Not really a big deal until I wanted to sort it.
Turns out the IList interface doesn't have a sort method built in.
I ended up using the ArrayList.Adapter(list).Sort(new MyComparer()) method to solve the problem but it just seemed a bit "ghetto" to me.
I toyed with writing an extension method, also with inheriting from IList and implementing my own Sort() method as well as casting to a List but none of these seemed overly elegant.
So my question is, does anyone have an elegant solution to sorting an IList
You can use LINQ:
using System.Linq;
IList<Foo> list = new List<Foo>();
IEnumerable<Foo> sortedEnum = list.OrderBy(f=>f.Bar);
IList<Foo> sortedList = sortedEnum.ToList();
This question inspired me to write a blog post: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
I think that, ideally, the .NET Framework would include a static sorting method that accepts an IList<T>, but the next best thing is to create your own extension method. It's not too hard to create a couple of methods that will allow you to sort an IList<T> as you would a List<T>. As a bonus you can overload the LINQ OrderBy extension method using the same technique, so that whether you're using List.Sort, IList.Sort, or IEnumerable.OrderBy, you can use the exact same syntax.
public static class SortExtensions
{
// Sorts an IList<T> in place.
public static void Sort<T>(this IList<T> list, Comparison<T> comparison)
{
ArrayList.Adapter((IList)list).Sort(new ComparisonComparer<T>(comparison));
}
// Sorts in IList<T> in place, when T is IComparable<T>
public static void Sort<T>(this IList<T> list) where T: IComparable<T>
{
Comparison<T> comparison = (l, r) => l.CompareTo(r);
Sort(list, comparison);
}
// Convenience method on IEnumerable<T> to allow passing of a
// Comparison<T> delegate to the OrderBy method.
public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> list, Comparison<T> comparison)
{
return list.OrderBy(t => t, new ComparisonComparer<T>(comparison));
}
}
// Wraps a generic Comparison<T> delegate in an IComparer to make it easy
// to use a lambda expression for methods that take an IComparer or IComparer<T>
public class ComparisonComparer<T> : IComparer<T>, IComparer
{
private readonly Comparison<T> _comparison;
public ComparisonComparer(Comparison<T> comparison)
{
_comparison = comparison;
}
public int Compare(T x, T y)
{
return _comparison(x, y);
}
public int Compare(object o1, object o2)
{
return _comparison((T)o1, (T)o2);
}
}
With these extensions, sort your IList just like you would a List:
IList<string> iList = new []
{
"Carlton", "Alison", "Bob", "Eric", "David"
};
// Use the custom extensions:
// Sort in-place, by string length
iList.Sort((s1, s2) => s1.Length.CompareTo(s2.Length));
// Or use OrderBy()
IEnumerable<string> ordered = iList.OrderBy((s1, s2) => s1.Length.CompareTo(s2.Length));
There's more info in the post: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
How about using LINQ To Objects to sort for you?
Say you have a IList<Car>, and the car had an Engine property, I believe you could sort as follows:
from c in list
orderby c.Engine
select c;
Edit: You do need to be quick to get answers in here. As I presented a slightly different syntax to the other answers, I will leave my answer - however, the other answers presented are equally valid.
You're going to have to do something like that i think (convert it into a more concrete type).
Maybe take it into a List of T rather than ArrayList, so that you get type safety and more options for how you implement the comparer.
The accepted answer by #DavidMills is quite good, but I think it can be improved upon. For one, there is no need to define the ComparisonComparer<T> class when the framework already includes a static method Comparer<T>.Create(Comparison<T>). This method can be used to create an IComparison on the fly.
Also, it casts IList<T> to IList which has the potential to be dangerous. In most cases that I have seen, List<T> which implements IList is used behind the scenes to implement IList<T>, but this is not guaranteed and can lead to brittle code.
Lastly, the overloaded List<T>.Sort() method has 4 signatures and only 2 of them are implemented.
List<T>.Sort()
List<T>.Sort(Comparison<T>)
List<T>.Sort(IComparer<T>)
List<T>.Sort(Int32, Int32, IComparer<T>)
The below class implements all 4 List<T>.Sort() signatures for the IList<T> interface:
using System;
using System.Collections.Generic;
public static class IListExtensions
{
public static void Sort<T>(this IList<T> list)
{
if (list is List<T> listImpl)
{
listImpl.Sort();
}
else
{
var copy = new List<T>(list);
copy.Sort();
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, Comparison<T> comparison)
{
if (list is List<T> listImpl)
{
listImpl.Sort(comparison);
}
else
{
var copy = new List<T>(list);
copy.Sort(comparison);
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, IComparer<T> comparer)
{
if (list is List<T> listImpl)
{
listImpl.Sort(comparer);
}
else
{
var copy = new List<T>(list);
copy.Sort(comparer);
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, int index, int count,
IComparer<T> comparer)
{
if (list is List<T> listImpl)
{
listImpl.Sort(index, count, comparer);
}
else
{
var range = new List<T>(count);
for (int i = 0; i < count; i++)
{
range.Add(list[index + i]);
}
range.Sort(comparer);
Copy(range, 0, list, index, count);
}
}
private static void Copy<T>(IList<T> sourceList, int sourceIndex,
IList<T> destinationList, int destinationIndex, int count)
{
for (int i = 0; i < count; i++)
{
destinationList[destinationIndex + i] = sourceList[sourceIndex + i];
}
}
}
Usage:
class Foo
{
public int Bar;
public Foo(int bar) { this.Bar = bar; }
}
void TestSort()
{
IList<int> ints = new List<int>() { 1, 4, 5, 3, 2 };
IList<Foo> foos = new List<Foo>()
{
new Foo(1),
new Foo(4),
new Foo(5),
new Foo(3),
new Foo(2),
};
ints.Sort();
foos.Sort((x, y) => Comparer<int>.Default.Compare(x.Bar, y.Bar));
}
The idea here is to leverage the functionality of the underlying List<T> to handle sorting whenever possible. Again, most IList<T> implementations that I have seen use this. In the case when the underlying collection is a different type, fallback to creating a new instance of List<T> with elements from the input list, use it to do the sorting, then copy the results back to the input list. This will work even if the input list does not implement the IList interface.
try this **USE ORDER BY** :
public class Employee
{
public string Id { get; set; }
public string Name { get; set; }
}
private static IList<Employee> GetItems()
{
List<Employee> lst = new List<Employee>();
lst.Add(new Employee { Id = "1", Name = "Emp1" });
lst.Add(new Employee { Id = "2", Name = "Emp2" });
lst.Add(new Employee { Id = "7", Name = "Emp7" });
lst.Add(new Employee { Id = "4", Name = "Emp4" });
lst.Add(new Employee { Id = "5", Name = "Emp5" });
lst.Add(new Employee { Id = "6", Name = "Emp6" });
lst.Add(new Employee { Id = "3", Name = "Emp3" });
return lst;
}
**var lst = GetItems().AsEnumerable();
var orderedLst = lst.OrderBy(t => t.Id).ToList();
orderedLst.ForEach(emp => Console.WriteLine("Id - {0} Name -{1}", emp.Id, emp.Name));**
Found this thread while I was looking for a solution to the exact problem described in the original post. None of the answers met my situation entirely, however. Brody's answer was pretty close. Here is my situation and solution I found to it.
I have two ILists of the same type returned by NHibernate and have emerged the two IList into one, hence the need for sorting.
Like Brody said I implemented an ICompare on the object (ReportFormat) which is the type of my IList:
public class FormatCcdeSorter:IComparer<ReportFormat>
{
public int Compare(ReportFormat x, ReportFormat y)
{
return x.FormatCode.CompareTo(y.FormatCode);
}
}
I then convert the merged IList to an array of the same type:
ReportFormat[] myReports = new ReportFormat[reports.Count]; //reports is the merged IList
Then sort the array:
Array.Sort(myReports, new FormatCodeSorter());//sorting using custom comparer
Since one-dimensional array implements the interface System.Collections.Generic.IList<T>, the array can be used just like the original IList.
Useful for grid sorting this method sorts list based on property names. As follow the example.
List<MeuTeste> temp = new List<MeuTeste>();
temp.Add(new MeuTeste(2, "ramster", DateTime.Now));
temp.Add(new MeuTeste(1, "ball", DateTime.Now));
temp.Add(new MeuTeste(8, "gimm", DateTime.Now));
temp.Add(new MeuTeste(3, "dies", DateTime.Now));
temp.Add(new MeuTeste(9, "random", DateTime.Now));
temp.Add(new MeuTeste(5, "call", DateTime.Now));
temp.Add(new MeuTeste(6, "simple", DateTime.Now));
temp.Add(new MeuTeste(7, "silver", DateTime.Now));
temp.Add(new MeuTeste(4, "inn", DateTime.Now));
SortList(ref temp, SortDirection.Ascending, "MyProperty");
private void SortList<T>(
ref List<T> lista
, SortDirection sort
, string propertyToOrder)
{
if (!string.IsNullOrEmpty(propertyToOrder)
&& lista != null
&& lista.Count > 0)
{
Type t = lista[0].GetType();
if (sort == SortDirection.Ascending)
{
lista = lista.OrderBy(
a => t.InvokeMember(
propertyToOrder
, System.Reflection.BindingFlags.GetProperty
, null
, a
, null
)
).ToList();
}
else
{
lista = lista.OrderByDescending(
a => t.InvokeMember(
propertyToOrder
, System.Reflection.BindingFlags.GetProperty
, null
, a
, null
)
).ToList();
}
}
}
Here's an example using the stronger typing. Not sure if it's necessarily the best way though.
static void Main(string[] args)
{
IList list = new List<int>() { 1, 3, 2, 5, 4, 6, 9, 8, 7 };
List<int> stronglyTypedList = new List<int>(Cast<int>(list));
stronglyTypedList.Sort();
}
private static IEnumerable<T> Cast<T>(IEnumerable list)
{
foreach (T item in list)
{
yield return item;
}
}
The Cast function is just a reimplementation of the extension method that comes with 3.5 written as a normal static method. It is quite ugly and verbose unfortunately.
In VS2008, when I click on the service reference and select "Configure Service Reference", there is an option to choose how the client de-serializes lists returned from the service.
Notably, I can choose between System.Array, System.Collections.ArrayList and System.Collections.Generic.List
using System.Linq;
var yourList = SomeDAO.GetRandomThings();
yourList.ToList().Sort( (thing, randomThing) => thing.CompareThisProperty.CompareTo( randomThing.CompareThisProperty ) );
That's pretty !ghetto.
Found a good post on this and thought I'd share. Check it out HERE
Basically.
You can create the following class and IComparer Classes
public class Widget {
public string Name = string.Empty;
public int Size = 0;
public Widget(string name, int size) {
this.Name = name;
this.Size = size;
}
}
public class WidgetNameSorter : IComparer<Widget> {
public int Compare(Widget x, Widget y) {
return x.Name.CompareTo(y.Name);
}
}
public class WidgetSizeSorter : IComparer<Widget> {
public int Compare(Widget x, Widget y) {
return x.Size.CompareTo(y.Size);
}
}
Then If you have an IList, you can sort it like this.
List<Widget> widgets = new List<Widget>();
widgets.Add(new Widget("Zeta", 6));
widgets.Add(new Widget("Beta", 3));
widgets.Add(new Widget("Alpha", 9));
widgets.Sort(new WidgetNameSorter());
widgets.Sort(new WidgetSizeSorter());
But Checkout this site for more information... Check it out HERE
Is this a valid solution?
IList<string> ilist = new List<string>();
ilist.Add("B");
ilist.Add("A");
ilist.Add("C");
Console.WriteLine("IList");
foreach (string val in ilist)
Console.WriteLine(val);
Console.WriteLine();
List<string> list = (List<string>)ilist;
list.Sort();
Console.WriteLine("List");
foreach (string val in list)
Console.WriteLine(val);
Console.WriteLine();
list = null;
Console.WriteLine("IList again");
foreach (string val in ilist)
Console.WriteLine(val);
Console.WriteLine();
The result was:
IList
B
A
C
List
A
B
C
IList again
A
B
C
This looks MUCH MORE SIMPLE if you ask me. This works PERFECTLY for me.
You could use Cast() to change it to IList then use OrderBy():
var ordered = theIList.Cast<T>().OrderBy(e => e);
WHERE T is the type eg. Model.Employee or Plugin.ContactService.Shared.Contact
Then you can use a for loop and its DONE.
ObservableCollection<Plugin.ContactService.Shared.Contact> ContactItems= new ObservableCollection<Contact>();
foreach (var item in ordered)
{
ContactItems.Add(item);
}
Convert your IList into List<T> or some other generic collection and then you can easily query/sort it using System.Linq namespace (it will supply bunch of extension methods)

Categories

Resources