Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
899
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
952
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
942
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1727
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4400
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Сортировка IList в C#
Так что сегодня я столкнулся с интересной проблемой. У нас есть веб-служба WCF, которая возвращает IList. На самом деле ничего особенного, пока я не захотел разобраться с этим.
Оказывается, интерфейс IList не имеет встроенного метода сортировки.
В конечном итоге я использовал метод ArrayList.Adapter(list).Sort(new MyComparer()) , чтобы решить эту проблему, но он просто показался мне немного "ghetto".
Я играл с написанием метода расширения, а также с наследованием от IList и реализацией моего собственного метода Sort(), а также приведением к списку, но ни один из них не казался слишком элегантным.
Поэтому мой вопрос заключается в том, есть ли у кого-нибудь элегантное решение для сортировки IList
Этот вопрос вдохновил меня написать сообщение в блоге: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
Я думаю, что в идеале фреймворк .NET будет включать в себя статический метод сортировки, который принимает IList<T>,, но следующая лучшая вещь-это создать свой собственный метод расширения. Не слишком сложно создать пару методов, которые позволят вам сортировать IList<T> так же, как и List<T>., в качестве бонуса вы можете перегрузить метод расширения LINQ OrderBy, используя тот же метод, так что независимо от того, используете ли вы List.Sort, IList.Sort или IEnumerable.OrderBy, вы можете использовать точно такой же синтаксис.
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));
}
// 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);
}
}
С помощью этих расширений сортируйте свой IList так же, как и список:
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));
Там больше информации в посте: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
Как насчет использования LINQ для сортировки объектов для вас?
Допустим, у вас есть IList<Car>, а у автомобиля была Engine собственность, я думаю, вы могли бы отсортировать следующим образом:
from c in list
orderby c.Engine
select c;
Правка: вам действительно нужно быть быстрым, чтобы получить ответы здесь. Поскольку я представил несколько иной синтаксис для других ответов, я оставлю свой ответ - однако, другие представленные ответы одинаково верны.
Принятый ответ @DavidMills довольно хорош, но я думаю, что его можно улучшить. Во-первых, нет необходимости определять класс ComparisonComparer<T> , когда платформа уже включает статический метод Comparer<T>.Create(Comparison<T>) . Этот метод можно использовать для создания IComparison на лету.
Кроме того, он бросает от IList<T> до IList , что потенциально может быть опасным. В большинстве случаев, которые я видел, List<T> , который реализует IList , используется за кулисами для реализации IList<T>, но это не гарантируется и может привести к хрупкому коду.
Наконец, перегруженный метод List<T>.Sort() имеет 4 сигнатуры, и только 2 из них реализованы.
List<T>.Sort()List<T>.Sort(Comparison<T>)List<T>.Sort(IComparer<T>)List<T>.Sort(Int32, Int32, IComparer<T>)
Приведенный ниже класс реализует все 4 сигнатуры List<T>.Sort() для интерфейса IList<T> :
using System;
using System.Collections.Generic;
public static class IListExtensions
{
public static void Sort<T>(this IList<T> list)
{
if (list is List<T>)
{
((List<T>)list).Sort();
}
else
{
List<T> 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>)
{
((List<T>)list).Sort(comparison);
}
else
{
List<T> 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>)
{
((List<T>)list).Sort(comparer);
}
else
{
List<T> 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>)
{
((List<T>)list).Sort(index, count, comparer);
}
else
{
List<T> 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];
}
}
}
Использование:
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));
}
Идея здесь заключается в том, чтобы использовать функциональность базового List<T> для обработки сортировки, когда это возможно. Опять же, большинство реализаций IList<T> , которые я видел, используют это. В случае, когда базовая коллекция имеет другой тип, выполните резервное копирование для создания нового экземпляра List<T> с элементами из входного списка, используйте его для выполнения сортировки, а затем скопируйте результаты обратно в входной список. Это будет работать, даже если входной список не реализует интерфейс IList .
Полезно для сортировки сетки этот метод сортирует список на основе имен свойств. Как следует из примера.
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();
}
}
}
Я нашел эту тему, когда искал решение точной проблемы, описанной в оригинальном посте. Однако ни один из ответов полностью не соответствовал моей ситуации. Ответ Броуди был довольно близок. Вот моя ситуация и решение, которое я нашел для нее.
У меня есть два ILists одного типа, возвращенных NHibernate, и два IList превратились в один, отсюда необходимость сортировки.
Как и сказал Броди, я реализовал ICompare на объекте (ReportFormat), который является типом моего IList:
public class FormatCcdeSorter:IComparer<ReportFormat>
{
public int Compare(ReportFormat x, ReportFormat y)
{
return x.FormatCode.CompareTo(y.FormatCode);
}
}
Затем я преобразую объединенный IList в массив того же типа:
ReportFormat[] myReports = new ReportFormat[reports.Count]; //reports is the merged IList
Затем отсортируйте массив:
Array.Sort(myReports, new FormatCodeSorter());//sorting using custom comparer
Поскольку одномерный массив реализует интерфейс System.Collections.Generic.IList<T>, массив можно использовать так же, как и исходный IList.
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));**
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));**
Является ли это правильным решением?
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();
Результат был таков: IList Б Один C
Список Один Б C
Опять IList Один Б C
Нашел хороший пост по этому поводу и подумал, что поделюсь. Проверьте это HERE
В основном.
Вы можете создать следующие классы class и IComparer
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);
}
}
Затем, если у вас есть IList, вы можете отсортировать его следующим образом.
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());
Но проверьте этот сайт для получения дополнительной информации... Проверьте это HERE
Вот пример использования более сильного набора текста. Хотя не уверен, что это обязательно лучший способ.
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;
}
}
Приведенная функция - это всего лишь повторная реализация метода расширения, который поставляется с 3.5, записанным как обычный статический метод. К сожалению, он довольно уродлив и многословен.