views:

150

answers:

3

i have a list of Person objects. i want to convert to a dictionary where the key is the first and last name (concatenated) and the value is the Person object.

the issue is that i have some duplicates people so this blows up if i use this code:

    private Dictionary<string, Person> _people = new Dictionary<string, Person>();

_people = personList.ToDictionary(e => e.FirstandLastName, StringComparer.OrdinalIgnoreCase);

i know it sounds weird but i dont really care about duplicates names for now. If there are multiple names i just want to grab one. Is there anyway i can write this code above so it just takes one of the names and doesn't blow up on duplicates?

+2  A: 
var _people = personList
    .GroupBy(p => p.FirstandLastName, StringComparer.OrdinalIgnoreCase)
    .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase);

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

var _people = new Dictionary<string, Person>(StringComparer.OrdinalIgnoreCase);
foreach (var p in personList)
{
    _people[p.FirstandLastName] = p;
}
LukeH
+1 very elegant (i will vote ASAP - have no more votes for today :) )
onof
There's a max amount of votes a day? :$
Carra
+2  A: 

Here's the obvious, non linq solution:

foreach(var person in personList)
{
  if(!myDictionary.Keys.Contains(person.FirstAndLastName))
    myDictionary.Add(person.FirstAndLastName, person);
}
Carra
@Carra - thats so 2007 :)
ooo
that doesn't ignore case
onof
Yeah, about time we update from the .net 2.0 framework at work... @onof Not exactly hard to ignore case. Just add all keys in uppercase.
Carra
@Carra - how would i make this case insensitive
ooo
Or create the dictionary with a StringComparer that will ignore the case, if thats what you need, then your adding/checking code doesn't care if you're ignoring case or not.
Binary Worrier
+1  A: 

To handle eliminating duplicates, implement an IEqualityComparer<Person> that can be used in the Distinct() method, and then getting your dictionary will be easy. Given:

class PersonComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return x.FirstAndLastName.Equals(y.FirstAndLastName, StringComparison.OrdinalIgnoreCase);
    }

    public int GetHashCode(Person obj)
    {
        return obj.FirstAndLastName.ToUpper().GetHashCode();
    }
}

class Person
{
    public string FirstAndLastName { get; set; }
}

Get your dictionary:

List<Person> people = new List<Person>()
{
    new Person() { FirstAndLastName = "Bob Sanders" },
    new Person() { FirstAndLastName = "Bob Sanders" },
    new Person() { FirstAndLastName = "Jane Thomas" }
};

Dictionary<string, Person> dictionary =
    people.Distinct(new PersonComparer()).ToDictionary(p => p.FirstAndLastName, p => p);
Anthony Pegram