Применение LINQ к объектам Group By и Sort By к универсальному списку <T>(C #) - PullRequest
5 голосов
/ 19 мая 2009

Мне трудно создавать рабочие предложения Group By и Sort By для универсального List myList. В myList есть список свойств «Настройки», который сам содержит список «дочерних» свойств для каждой компании.

Я хочу группировать по отраслям и по каждой отрасли, сортировать по названию компании. Мое намерение было бы так:

string groupSetting = "Industry";
sortSetting = "BusinessName";
myList.GroupBy(p => p.Settings.Find(s => s.Name == groupSetting)).OrderBy(p => p.Settings.Find(t => t.Name == sortSetting));

Однако я получаю сообщение об ошибке: ' System.Linq.IGrouping не содержит определения для параметров и метода расширения. Параметры, принимающие первый аргумент типа System.Linq.Igrouping, могут быть найдены .... ', что означает, что я не могу вызвать заказ с помощью пункт без каких-либо преобразований или дополнительной обработки.

Я пробовал все виды вещей, чтобы разделить это и заставить его работать, но я что-то упустил. Любая помощь приветствуется

1 Ответ

13 голосов
/ 19 мая 2009

Ваша проблема в том, что GroupBy не возвращает один список настроек, он возвращает «список списков». Это IGrouping, который вы видите.

Вам нужно перебрать каждую группу в IGrouping, отсортировать эту группу, а затем перебрать каждый элемент в группе. Обратите внимание:

public static void Main( string[] args )
{
    var groupSetting = "Industry";

    // step 1: group the data. Note this doesn't actually create copies of the data as
    // it's all lazy loaded
    // BEWARE. If a company doesn't have the "Industry" setting, this will throw an exception
    var grouped = companies.GroupBy(c => c.Settings.First(s => s.Name == groupSetting).Value);
    foreach( var group in grouped )
    {
        Console.WriteLine(group.Key);// this is the Value that came out of the GroupBy

        // Note how we have to do the ordering within each individual group. 
        // It doesn't make sense to try group them in one hit like in your question
        foreach( var item in group.OrderBy(bus => bus.Name) )
            Console.WriteLine(" - " + item.Name);
    }
}

Структуры данных, представленные для ясности:

struct Setting { public string Name; public string Value; }
struct Business { public string Name; public IEnumerable<Setting> Settings; }

static IEnumerable<Business> companies = new[]{
    new Business{ Name = "XYZ Inc.", Settings = new[]{ 
        new Setting{ Name="Age", Value="27"},
        new Setting{ Name="Industry", Value="IT"}
    }},
    new Business{ Name = "Programmers++", Settings = new[]{ 
        new Setting{ Name="Age", Value="27"},
        new Setting{ Name="Industry", Value="IT"}
    }},
    new Business{ Name = "Jeff's Luxury Salmon", Settings = new[]{ 
        new Setting{ Name="Age", Value="63"},
        new Setting{ Name="Industry", Value="Sports"}
    }},
    new Business{ Name = "Bank of Khazakstan", Settings = new[]{ 
        new Setting{ Name="Age", Value="30"},
        new Setting{ Name="Industry", Value="Finance"}
    }},
};

Это приводит к следующему выводу: скопируйте / вставьте код, запустите его и поиграйте с ним

IT
 - Programmers++
 - XYZ Inc.
Sports
 - Jeff's Luxury Salmon
Finance
 - Bank of Khazakstan
...