【问题标题】:Reducing duplicates in a dictionary using LINQ in C#在 C# 中使用 LINQ 减少字典中的重复项
【发布时间】:2012-02-25 10:26:36
【问题描述】:

我正在尝试使用 LINQ 从现有字典创建一个新字典,并在此过程中删除重复项。

现有字典如下:

Dictionary<LoaderConfig, List<ColumnInfo>> InvalidColumns = new Dictionary<LoaderConfig, List<ColumnInfo>>();

public struct LoaderConfig
{
    public string ObjectName { get; set; }
    public DateTime? LoadDate { get; set; }
    public string Load { get; set; }
    public string TableName { get; set; }
}

public struct ColumnInfo
{
    public string ColumnName { get; set; }
    public string DataType { get; set; }
    public int DataLength { get; set; }
}

我想要结束的是Dictionary&lt;string, List&lt;ColumnInfo&gt;&gt;,其中键是 LoaderConfig 对象的 TableName 属性,并且 ColumnInfo 对象的列表对于每个 TableName 都是唯一的。

我是根据我发现的另一篇文章开始的:

var alterations = InvalidColumns
    .GroupBy(pair => pair.Key.TableName)
    .Select(group => group.First())
    .ToDictionary(pair => pair.Key.TableName, pair => pair.Value);

由于 First(),这不起作用。我想有一种方法可以使用 LINQ 扩展来实现这一点,我只需要一些帮助来找到它。

谢谢!

【问题讨论】:

  • 哎哟。为什么 LoaderConfigstruct ?我认为不应该。
  • 什么是你的副本?是表名和列名吗?是您的LoaderConfigColumnInfo 的所有值吗?
  • 一个副本将是 LoaderConfig.TableName 和 ColumnInfo 对象的组合。
  • 为什么LoaderConfig 不是struct?我是 C# 的新手,来自 Java,所以任何提示都将不胜感激!
  • 应该是一堂课。几乎从不需要结构体。但是现在改变它可能需要太多的工作(平等也会改变)。

标签: c# linq dictionary


【解决方案1】:
  //untested
  var alterations = InvalidColumns
             .GroupBy(pair => pair.Key.TableName)
             .ToDictionary(group => group.Key, 
                           group => group.SelectMany(g => g.Value).Distinct());

你必须以某种方式在.Distinct() 工作。

Edit 确实需要 Distinct(),添加。

【讨论】:

  • 编辑您的答案: var alters = InvalidColumns .GroupBy(pair => pair.Key.MARSTable) .ToDictionary(group => group.Key, group => group.SelectMany(g => g .Value).Distinct());这对我有用。
【解决方案2】:
Dictionary<string, List<ColumnInfo>> alterations = InvalidColumns
    .SelectMany(p => p.Value, (p, col) => new { p.Key.TableName, col })
    .GroupBy(single => single.TableName, single => single.col)
    .ToDictionary(g => g.Key, g => g.Distinct().ToList());

SelectMany 将列列表展平,即创建表名和单个列的枚举。然后这个枚举按表名重新分组。

【讨论】:

    【解决方案3】:

    我个人会做这样的事情:

    首先为ColumnInfo创建一个IEqualityComparer(Distinct使用)

        public struct ColumnInfo
        {
            public string ColumnName { get; set; }
            public string DataType { get; set; }
            public int DataLength { get; set; }
    
            public class ColumnNameComparer : IEqualityComparer<ColumnInfo>
            {
                public bool Equals(ColumnInfo x, ColumnInfo y)
                {
                    return x.ColumnName == y.ColumnName;
                }
    
                public int GetHashCode(ColumnInfo obj)
                {
                    return obj.ColumnName.GetHashCode();
                }
            }
        }
    

    然后查询:

            var colComparer = new ColumnInfo.ColumnNameComparer();
            Dictionary<string, List<ColumnInfo>> res = InvalidColumns
                .GroupBy(i => i.Key.TableName)
                .ToDictionary(i => i.Key, i => i.SelectMany(j => j.Value.Distinct(colComparer)).ToList());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多