我有一个Person对象列表。我想转换为Dictionary,其中键是第一个和最后一个名字(连接),值是Person对象。

问题是我有一些重复的人,所以这爆炸如果我使用以下代码:

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

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

我知道这听起来很奇怪,但我现在真的不关心重复的名字。如果有多个名字,我只想取一个。有没有什么方法可以让上面的代码只取其中一个名字而不会重复?


当前回答

您还可以使用ToLookup LINQ函数,然后您几乎可以与Dictionary互换使用该函数。

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

这将在LukeH的回答中执行GroupBy,但将给出Dictionary提供的散列。因此,您可能不需要将它转换为Dictionary,但只要在需要访问键的值时使用LINQ First函数即可。

其他回答

LINQ的解决方案:

// 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);

如果你更喜欢非linq解决方案,那么你可以这样做:

// 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;
}

您还可以使用ToLookup LINQ函数,然后您几乎可以与Dictionary互换使用该函数。

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

这将在LukeH的回答中执行GroupBy,但将给出Dictionary提供的散列。因此,您可能不需要将它转换为Dictionary,但只要在需要访问键的值时使用LINQ First函数即可。

如果我们想要返回字典中的所有Person(而不是只有一个Person),我们可以:

var _people = personList
.GroupBy(p => p.FirstandLastName)
.ToDictionary(g => g.Key, g => g.Select(x=>x));

从Carra的解开始,你也可以把它写成:

foreach(var person in personList.Where(el => !myDictionary.ContainsKey(el.FirstAndLastName)))
{
    myDictionary.Add(person.FirstAndLastName, person);
}

下面是一个明显的非linq解决方案:

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

如果你不介意总是添加最后一个,你可以避免这样的双重查找:

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