使用LINQ创建字典并避免"已添加相同键的项目"错误

Tom*_*eck 16 c# linq

我想在字典中找到一个键并在找到它时替换该值,或者如果不是则添加键/值.

码:

public class MyObject
{

    public string UniqueKey { get; set; }
    public string Field1 { get; set; }
    public string Field2 { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

LINQ解决方案(抛出An item with the same key has already been added.):

Dictionary<string, MyObject> objectDict = csvEntries.ToDictionary(csvEntry => csvEntry.ToMyObject().UniqueKey, csvEntry => csvEntry.ToMyObject());
Run Code Online (Sandbox Code Playgroud)

ForEach解决方案(工作):

Dictionary<string, MyObject> objectDict = new Dictionary<string, MyObject>();
foreach (CSVEntry csvEntry in csvEntries)
{

    MyObject obj = csvEntry.ToMyObject();

    if (objectDict.ContainsKey(obj.UniqueKey))
    {
        objectDict[obj.UniqueKey] = obj;
    }
    else {
        objectDict.Add(obj.UniqueKey, obj);
    }

}
Run Code Online (Sandbox Code Playgroud)

我真的很喜欢LINQ解决方案,但就其而言,它会引发上述错误.有没有避免错误和使用LINQ的好方法?

Tim*_*ter 15

您可以使用GroupBy创建唯一键:

Dictionary<string, MyObject> objectDict = csvEntries
    .Select(csvEntry => csvEntry.ToMyObject())
    .GroupBy(x => x.UniqueKey)
    .ToDictionary(grp => grp.Key, grp => grp.First());
Run Code Online (Sandbox Code Playgroud)

但是,grp.First()您可以使用ToList或创建集合ToArray.在这种情况下,如果重复键,您不会使用任意对象.

另一种选择是使用Lookup<TKey, TValue>允许重复键甚至不存在键的a,在这种情况下你得到一个空序列.

var uniqueKeyLookup = csvEntries
    .Select(csvEntry => csvEntry.ToMyObject())
    .ToLookup(x => x.UniqueKey);
IEnumerable<MyObject> objectsFor1234 = uniqueKeyLookup["1234"]; // empty if it doesn't exist
Run Code Online (Sandbox Code Playgroud)

  • 第一个解决方案对我有用,但是`ToDictionary(grp =&gt; grp.Key,grp =&gt; grp.First());`必须是ToDictionary(grp =&gt; grp.Key,grp =&gt; grp.Last() );`,因为我希望键的值在以后的条目中被“替换”。 (2认同)