2015-06-09 5 views
2

Вот мой объект:Сортировка в списке объектов, который содержит словарь

public class A 
{ 
public string Name { get; set; }  
public Dictionary<int, List<int>> Years { get; set; } 
} 

Словарь содержит список лет затем, список месяцев. Я ищу сортировать список A по году первый год.

словарь образца на каждом A:

{2015,new List(){3,4,5,6}} 
{2016,new List(){2,8,9,10}} 

Если у меня есть несколько лет, то он может сортировать что-то вроде: 2015 затем 2015, 2016 затем 2016

я не смог реализовать IComparable или использовать любые существующие такие как OrderBy или Sort. Благодаря!

+0

Как бы вы своего рода 'A1: ({10, {0}}, {12, {0}}), A2: ({11, {0}}, {13, {0}}) '? Если 'A1' идти первым, потому что самый низкий год у него есть до самого низкого года' A2'? Или вы разбиваете каждый A вверх и сортируете его в один большой A, например '{10, ..}, {11, ..}, {12, ..}, {13, ..}'? – SimpleVar

+0

Да, сначала A1, затем A2. Никакой раскол, поскольку он будет дублировать объект А. Спасибо! –

ответ

1

Я добавил IComparable в свой класс (который, конечно, вы можете извлечь и передать в качестве делегата .....)

fiddlerlink

примечание: Для простоты я предполагаю, что списки отсортированы. в противном случае добавьте свои виды в соответствующее место в вашем сценарии :)

в основном вернуть первый сравнительный пример, который не равен годам или месяцам. вы можете назвать это MyListOfAs.Sort();

public class A:IComparable<A> 
{ 
    public string Name { get; set; } 
    public Dictionary<int, List<int>> Years { get; set; } 

    private int complists(List<int> a, List<int> b) 
    { 
     var iret = (from i in Enumerable.Range(0, Math.Min(a.Count, b.Count)) 
        where a[i].CompareTo(b[i]) != 0 
        select a[i] > b[i] ? 1 : -1).FirstOrDefault(); 

     return iret; 
    } 
    public int CompareTo(A other) 
    { 
     var mykeys = this.Years.Keys.ToList(); 
     var otherkeys = other.Years.Keys.ToList(); 

     var iret = (from i in Enumerable.Range(0, Math.Min(mykeys.Count, otherkeys.Count)) 
        let yearDiff = mykeys[i].CompareTo(otherkeys[i]) 
        let monthDiff = complists(this.Years[mykeys[0]], other.Years[otherkeys[0]]) 
        where yearDiff != 0 || monthDiff != 0 
        select yearDiff != 0 ? yearDiff : monthDiff).FirstOrDefault(); 

     return iret != 0 ? iret : mykeys.Count > otherkeys.Count ? 1 : mykeys.Count < otherkeys.Count ? -1 : 0; 
    } } 
+0

Спасибо! Проверьте https://dotnetfiddle.net/w7Sywg Любая идея, почему «a14» не подходит? Он имеет только 2015. –

+0

в ретро-спецификации. Думаю, я был неправ (я обновил решение выше). Я изменил с x в a от y в b до порядкового сравнения, а затем добавил количество списков, которые я не сделал примите во внимание первый раз:/ Надеюсь, это по крайней мере доставит вас по правой (полезной) дорожке :) – cechode

+0

Спасибо. Его все еще не работает. Я добавил еще один объект с 2015 года. Пожалуйста, проверьте скрипту. –

1

Я думаю, что это нужно сделать, это: listOfA.OrderBy(a => a.Years.Min(y => y.Key + y.Value.Min()/13d))

Если низкий год и месяц в словаре в 2000 Ян, например, это значение будет 2000 + 1/13 = 2000.0769

Тогда все, что осталось, чтобы выбрать наименьшее значение из каждого словаря и сортировать их по этому значению.

Примечание что значение 13 может быть 20, а также, если вы хотите более хорошие номера по какой-то причине, но большая часть 12/x должна быть меньше, чем 1, с тем чтобы придать большее значение для надлежаще года, так x должно быть больше 12. Это предполагает, что диапазон месяцев составляет от 1 до 12 включительно.


Пример I/O:

var listOfA = new List<A> 
       { 
        new A 
        { 
         Name = "a1", 
         Years = new Dictionary<int, List<int>> 
           { 
            {2015, new List<int> {3, 4, 5, 6}}, 
            {2016, new List<int> {2, 8, 9, 10}} 
           } 
        }, 
        new A 
        { 
         Name = "a2", 
         Years = new Dictionary<int, List<int>> 
           { 
            {2013, new List<int> {3, 4, 5, 6}}, 
            {2014, new List<int> {2, 8, 9, 10}} 
           } 
        }, 
        new A 
        { 
         Name = "a3", 
         Years = new Dictionary<int, List<int>> 
           { 
            {2015, new List<int> {3, 4, 5, 6}}, 
            {2014, new List<int> {2, 8, 9, 10}} 
           } 
        }, 
        new A 
        { 
         Name = "a4", 
         Years = new Dictionary<int, List<int>> 
           { 
            {2014, new List<int> {1, 4, 5, 6}}, 
            {2017, new List<int> {2, 8, 9, 10}} 
           } 
        } 
       }; 

// listOfA is now {a1, a2, a3, a4} 
listOfA = listOfA.OrderBy(a => a.Years.Min(y => y.Key + y.Value.Min()/13d)).ToList(); 
// listOfA is now {a2, a4, a3, a1} 
+0

Спасибо, Yorye! Это не работает для меня. Можете ли вы добавить два объекта с 2015 и 2016 годами? Его неудача в 2015 году. –

+0

Поделитесь пастебом вашей версии и ожидаемым заказом. – SimpleVar

+1

@YoryeNathan - Не используйте pastebin - попробуйте https://dotnetfiddle.net/ вместо этого. Вы можете запустить код там. – Enigmativity

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