Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert list to dictionary using linq and not worrying about duplicates

LINQ solution:

// Use the first value in group
var _people = personList
    .GroupBy(p => p.FirstandLastName, StringComparer.OrdinalIgnoreCase)
    .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase);

// Use the last value in group
var _people = personList
    .GroupBy(p => p.FirstandLastName, StringComparer.OrdinalIgnoreCase)
    .ToDictionary(g => g.Key, g => g.Last(), StringComparer.OrdinalIgnoreCase);

If you prefer a non-LINQ solution then you could do something like this:

// Use the first value in list
var _people = new Dictionary<string, Person>(StringComparer.OrdinalIgnoreCase);
foreach (var p in personList)
{
    if (!_people.ContainsKey(p.FirstandLastName))
        _people[p.FirstandLastName] = p;
}

// Use the last value in list
var _people = new Dictionary<string, Person>(StringComparer.OrdinalIgnoreCase);
foreach (var p in personList)
{
    _people[p.FirstandLastName] = p;
}

Here's the obvious, non linq solution:

foreach(var person in personList)
{
  if(!myDictionary.ContainsKey(person.FirstAndLastName))
    myDictionary.Add(person.FirstAndLastName, person);
}

If you don't mind always getting the last one added, you can avoid the double lookup like this:

foreach(var person in personList)
{
    myDictionary[person.FirstAndLastName] = person;
}

A Linq-solution using Distinct() and and no grouping is:

var _people = personList
    .Select(item => new { Key = item.Key, FirstAndLastName = item.FirstAndLastName })
    .Distinct()
    .ToDictionary(item => item.Key, item => item.FirstFirstAndLastName, StringComparer.OrdinalIgnoreCase);

I don't know if it is nicer than LukeH's solution but it works as well.


This should work with lambda expression:

personList.Distinct().ToDictionary(i => i.FirstandLastName, i => i);

You can also use the ToLookup LINQ function, which you then can use almost interchangeably with a Dictionary.

_people = personList
    .ToLookup(e => e.FirstandLastName, StringComparer.OrdinalIgnoreCase);
_people.ToDictionary(kl => kl.Key, kl => kl.First()); // Potentially unnecessary

This will essentially do the GroupBy in LukeH's answer, but will give the hashing that a Dictionary provides. So, you probably don't need to convert it to a Dictionary, but just use the LINQ First function whenever you need to access the value for the key.