Помогите Linqifying коллекции в словарь - PullRequest
6 голосов
/ 18 декабря 2009

Я рефакторинг этого кода и пытался придумать простое выражение linq для заполнения этого словаря.

IEnumerable<IHeaderRecord> headers = PopulateHeaders();
var headerLocationLookup = new Dictionary<string, IHeaderRecord>();

foreach (var header in headers)
{
//destination locations can repeat, if they do, dictionary should only contain the first header associated with a particular location
    if (!headerLocationLookup.ContainsKey(header.DestinationLocation)) 
    {
         headerLocationLookup[header.DestinationLocation] = header;
    }
}

Я мог только придумать реализацию собственного IEqualityComparer и использовать его в выражении, таком как этот ...

headers.Distinct(new CustomComparer()).ToDictionary();

Есть ли способ сделать все это встроенным без пользовательского IEqualityComparer? Заранее спасибо.

Ответы [ 3 ]

13 голосов
/ 18 декабря 2009
    var qry = headers.GroupBy(row => row.DestinationLocation)
        .ToDictionary(grp => grp.Key, grp => grp.First());

или (эквивалент):

    var dictionary = (from row  in headers
              group row by row.DestinationLocation)
              .ToDictionary(grp => grp.Key, grp => grp.First());

Интересно, однако, если ваш текущий код foreach уже не лучше - он не буферизует те, которые он собирается отбросить, например.

5 голосов
/ 18 декабря 2009

Некоторое время назад я написал сообщение в блоге , в котором показано, как можно создать перегрузки Distinct, использующие лямбда-выражение в качестве селектора ключа вместо пользовательского компаратора, который позволил бы написать:

headers.Distinct(h => h.DestinationLocation)
       .ToDictionary(h => h.DestinationLocation);

Он использует собственный компаратор внизу, но метод расширения создает этот материал для вас и делает его намного проще для чтения.

2 голосов
/ 18 декабря 2009
var headerLocationLookup = PopulateHeaders()
    .Aggregate(new Dictionary<string, IHeaderRecord>(), (header, d) => {
        if(d.ContainsKey(header.DestinationLocation)) 
            d[header.DestinationLocation] = header;

        return d;
    });

Я не думаю, что это более понятно, чем существующий код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...