c# - 可能有重复的键时如何添加到字典中?

标签 c# linq dictionary

需要将来自可能具有重复键的对象的一堆键/值对添加到字典中。仅将键的第一个不同实例(及其实例的值)添加到字典中。

下面是一个示例实现,起初看起来效果很好。

void Main()
{
    Dictionary<long, DateTime> items = new Dictionary<long, DateTime>();
    items = AllItems.Select(item =>
                    {
                        long value;
                        bool parseSuccess = long.TryParse(item.Key, out value);
                        return new { value = value, parseSuccess, item.Value };
                    })
                    .Where(parsed => parsed.parseSuccess && !items.ContainsKey(parsed.value))
                    .Select(parsed => new { parsed.value, parsed.Value })
                    .Distinct()
                    .ToDictionary(e => e.value, e => e.Value);
    Console.WriteLine(string.Format("Distinct: {0}{1}Non-distinct: {2}",items.Count, Environment.NewLine, AllItems.Count));

}

public List<KeyValuePair<string, DateTime>> AllItems
{
    get
    {
        List<KeyValuePair<string, DateTime>> toReturn = new List<KeyValuePair<string, DateTime>>();
        for (int i = 1000; i < 1100; i++)
        {
            toReturn.Add(new KeyValuePair<string, DateTime>(i.ToString(), DateTime.Now));
            toReturn.Add(new KeyValuePair<string, DateTime>(i.ToString(), DateTime.Now));
        }
        return toReturn;
    }
}


但是,如果将AllItems修改为返回更多对,则会发生ArgumentException:“已经添加了具有相同键的项。”

void Main()
{
    Dictionary<long, DateTime> items = new Dictionary<long, DateTime>();
    var AllItems = PartOne.Union(PartTwo);
    Console.WriteLine("Total items: " + AllItems.Count());
    items = AllItems.Select(item =>
                    {
                        long value;
                        bool parseSuccess = long.TryParse(item.Key, out value);
                        return new { value = value, parseSuccess, item.Value };
                    })
                    .Where(parsed => parsed.parseSuccess && !items.ContainsKey(parsed.value))
                    .Select(parsed => new { parsed.value, parsed.Value })
                    .Distinct()
                    .ToDictionary(e => e.value, e => e.Value);
    Console.WriteLine("Distinct: {0}{1}Non-distinct: {2}",items.Count, Environment.NewLine, AllItems.Count());

}

public IEnumerable<KeyValuePair<string, DateTime>> PartOne
{
    get
    {
        for (int i = 10000000; i < 11000000; i++)
        {
            yield return (new KeyValuePair<string, DateTime>(i.ToString(), DateTime.Now));
        }
    }
}
public IEnumerable<KeyValuePair<string, DateTime>> PartTwo
{
    get
    {
        for (int i = 10000000; i < 11000000; i++)
        {
            yield return (new KeyValuePair<string, DateTime>(i.ToString(), DateTime.Now));
        }
    }
}


做到这一点的最佳方法是什么?请注意,解决方案中需要使用long.TryParse,因为实际输入可能不包括有效的Int64。

最佳答案

仅键的第一个不同的实例(以及实例的值)
  应该添加到字典中。


您可以使用Enumerable.GroupBy方法并采用组中的第一个值来实现此目的:

items = AllItems.Select(item =>
                {
                    long value;
                    bool parseSuccess = long.TryParse(item.Key, out value);
                    return new { Key = value, parseSuccess, item.Value };
                })
                .Where(parsed => parsed.parseSuccess)
                .GroupBy(o => o.Key)
                .ToDictionary(e => e.Key, e => e.First().Value)

关于c# - 可能有重复的键时如何添加到字典中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7676711/

相关文章:

javascript - JavaScript 中的 C# 字典等价物

c# - 静态的线程安全

c# - 如何更改 Entity Framework 为 Datetime 生成 SQL 精度的方式

python - 将字典写入 CSV

c# - 奇怪的 LINQ 异常(索引越界)

c# - 提高 Linq SQL 查询性能

c# - 将嵌套类转换为字典

c# - 在 Dapper 中使用 Protocol Buffer 模型时如何将 C# ticks 映射到 PostgreSQL 时间戳?

c# - 我可以依赖使用 Web API 的 CallContext 吗?

c# - 通过 LINQ 检查分隔字段中的值