2015-09-06 2 views
0

У меня есть класс со строковым полем, которое я хочу сортировать, используя несколько условий.Пользовательский список Сортировать по нескольким условиям

Класс в вопросе

class Items 
{ 
    public string ItemType {get; set;} 
    public string Code {get; set;} 

    // other members elided 

    public Items(string _IT, string _Cd) 
    { 
     ItemType = _IT; 
     Code = _Cd; 
    } 
} 

Использование класса

List<Items> lstItemCol = new List<Items>(); 

lstItemCol.Add(new Items("EE", "12345")); 
lstItemCol.Add(new Items("WW", "5881")); 
lstItemCol.Add(new Items("LLL", "215458")); 
lstItemCol.Add(new Items("WW", "789")); 
lstItemCol.Add(new Items("EE", "582")); 

То, что я хочу сделать, это своего рода список, так что элементы упорядочены по ЭЭ с последующим WW затем LLL

Порядок вывода должен быть:

"EE", "582" 
"EE", "12345" 
"WW", "5881" 
"WW", "789" 
"LLL", "215458" 

Я не могу придумать элегантный способ сделать это, а затем добавить другое поле в класс (sortOrder) и отсортировать по этому вопросу: я бы предпочел избежать этого и просто сортировать по ItemType?

+0

Проверьте перегрузки 'List .Sort()'. Используйте произвольное сравнение. – siride

+0

Вы были бы достаточно счастливы, создав * новый * список, который сортируется так, как вы хотите? Если это так, LINQ, безусловно, путь. В противном случае пользовательское сравнение не должно быть слишком сложным ... –

+1

Ваш порядок сортировки не ясен. В частности, как сортировать элементы, когда ItemType равен – Amit

ответ

0

Существует два способа реализации этого в многоразовом и чистом виде.

  1. Реализовать IComparable на детале

  2. создать собственный Item компаратор и использовать его в качестве параметра по заказу из LINQ.

PS: Я бы также рекомендовал использовать единую форму для названия класса. Элемент не во множественном числе. Элементы обычно относятся к коллекциям.

PPS: Я также использовал linqpad, чтобы продемонстрировать реализацию.

void Main() 
{ 
    var lstItemCol = new List<Item>(); 

    lstItemCol.Add(new Item("EE", "12345")); 
    lstItemCol.Add(new Item("WW", "5881")); 
    lstItemCol.Add(new Item("LLL", "215458")); 
    lstItemCol.Add(new Item("WW", "789")); 
    lstItemCol.Add(new Item("EE", "582")); 

    lstItemCol.OrderBy(ic => ic).Dump(); 
    lstItemCol.OrderBy(ic => ic, new ItemComparer()).Dump(); 
} 

// Define other methods and classes here 

class Item : IComparable<Item>, IComparable 
{ 
    public string ItemType { get; set; } 
    public string Code { get; set; } 

    // other members elided 

    public Item(string _IT, string _Cd) 
    { 
     ItemType = _IT; 
     Code = _Cd; 
    } 

    public int CompareTo(Item other) 
    { 
     if (other == null) return 1; 
     var result = ItemType.Length.CompareTo(other.ItemType.Length); 
     if (result == 0) result = ItemType.CompareTo(other.ItemType); 
     if (result == 0) result = Code.Length.CompareTo(other.Code.Length); 
     if (result == 0) result = Code.CompareTo(other.Code); 
     return result; 
    } 
    int IComparable.CompareTo(object other) 
    { 
     return CompareTo(other as Item); 
    } 
} 

sealed class ItemComparer : FComparer<Item> 
{ 
    private static readonly Func<Item, Item, int> _comparer = (v1, v2) => 
    { 
     var result = v1.ItemType.Length.CompareTo(v2.ItemType.Length); 
     if (result == 0) result = v1.ItemType.CompareTo(v2.ItemType); 
     if (result == 0) result = v1.Code.Length.CompareTo(v2.Code.Length); 
     if (result == 0) result = v1.Code.CompareTo(v2.Code); 
     return result; 
    }; 

    public ItemComparer() 
     :base(_comparer) 
    { } 
} 

abstract class FComparer<T> : IComparer<T> 
{ 
    private readonly Func<T, T, int> _comparer; 

    protected FComparer(Func<T, T, int> comparer) 
    { _comparer = comparer; } 

    public int Compare(T v1, T v2) 
    { 
     return _comparer(v1, v2); 
    } 
} 
+0

. В качестве примечания к этому вы также можете использовать. Сортировка в списке, поскольку элемент реализован IComparable. Он будет работать по желанию без linq. – Max

Смежные вопросы