【问题标题】:Eleminate duplicates Items from a List<T> by foreach loop in C#通过 C# 中的 foreach 循环从 List<T> 中消除重复项
【发布时间】:2015-10-12 08:50:08
【问题描述】:

如何从项目列表中消除重复的项目(时间戳)。我有一个带有重复时间戳的项目列表。我想填写另一个响应列表,并通过 For each 循环消除基于唯一时间戳的重复记录。退货商品列表中只能有一个时间戳。

    public class InventoryDetails
    {
        public int InventoryDetailsId { get; set; }
        public int ItemName { get; set; }
        public int Price { get; set; }
        public DateTime Timestamp { get; set; }
    }

    public class InventoryDetailsResponse
    {
        public int InventoryDetailsId { get; set; }
        public int ItemName { get; set; }
        public int Price { get; set; }
        public DateTime Timestamp { get; set; }
    }

来自数据库的样本库存数据

101 , Item1, 500, 2015-06-24 16:00:03
102、第2、125、2015-07-01 01:20:03
103、Item1、500、2015-06-24 16:00:03
104、Item3、340、2015-07-04 09:10:12
105、Item4、059、2015-06-24 12:23:03
106、Item1、500、2015-06-24 16:00:03
107、第5、845、2015-07-11 15:30:03

// 需要根据时间戳去除重复记录。

public List<InventoryDetailsResponse> GetInventory()
        {
            List<InventoryDetails> result = FromDatabase();
            var list = new List<InventoryDetailsResponse>();

            foreach (InventoryDetails match in result)
            {
                var tc = new InventoryDetailsResponse
                {
                    InventoryDetailsId = match.InventoryDetailsId,
                    ItemName = match.ItemName,
                    Price = match.Price,
                    Timestamp = match.Timestamp  // Duplicate timestamp in database.
                };
                list.Add(tc);
            }
            return list;
        }

【问题讨论】:

  • 您要消除内存中或查询内部的重复项吗?
  • 如果你想在查询后做,你可以创建一个HashSet,在你的foreach中添加每个时间戳并在列表周围添加一个条件。添加以检查时间戳是否没有已经遇到了

标签: c# .net linq foreach lambda


【解决方案1】:

直接使用 Linq:

var myUniqueRecordsByTimestamp = GetInventory()
                                .GroupBy(x => x.Timestamp)
                                .Select(g => g.First());

GroupBy 操作将为您返回 IEnumerableIGrouping 项目(也是 IEnumerables)。

Source Answer 来自类似但不重复的问题。

【讨论】:

  • 这是第一个明智的答案,它不会破坏对象的 Equals 并且执行 OP 可能真正想要的...
  • 如果 OP 需要根据时间戳对记录进行重复数据删除,那么 OP 最可能想要的就是无法控制地抽泣。
  • @susheeltyagi,没问题,伙计:),如果对您有帮助,请考虑接受答案。
【解决方案2】:

我将它用于相同的目的,就像一个魅力:

List<InventoryDetails> list = result.GroupBy(x => x.Timestamp).Select(y => y.First()).ToList();

它根据指定的属性(此处为 Timestamp)对项目进行分组,并使用每个组的第一项构建一个新列表。

【讨论】:

    【解决方案3】:

    您可以使用 LINQ:

    public List<InventoryDetailsResponse> GetInventory()
    {
        List<InventoryDetails> result = FromDatabase();
        var list = new List<InventoryDetailsResponse>();
    
        foreach (InventoryDetails match in result)
        {
            var tc = new InventoryDetailsResponse
            {
                InventoryDetailsId = match.InventoryDetailsId,
                ItemName = match.ItemName,
                Price = match.Price,
                Timestamp = match.Timestamp  // Duplicate timestamp in database.
            };
            list.Add(tc);
         }
    
        var res = list.GroupBy(item => item.Timestamp).Select(g => g.First()).ToList();
        return res;
    }
    

    【讨论】:

      【解决方案4】:

      您可以为您的InventoryDetails 类覆盖Equals,例如:

      class InventoryDetails {
          public override Equals(object obj) {
              if (obj is InventoryDetails) {
                  InventoryDetails details = (InventoryDetails)obj;
                  return details.ItemName == this.ItemName && details.Price == this.Price && details.Timestamp == this.Timestamp;
              }
              return false;
          }
      }
      

      之后,您可以只使用List&lt;InventoryDetails&gt;.Distinct() 删除重复条目,因为具有相同Timestamp 的所有条目现在被认为是相等的。

      【讨论】:

      • 你的 equal 方法也应该包括对其他字段的检查
      • 这可能不是一个好主意 - 如果您使用其他字段,您的 equals 丢弃重复时间戳可能不起作用(假设其他字段不同),然后 Equals 的使用将少于直观...
      • 我只是忘记将其他字段添加到实现中。编辑了答案。
      • 然后它不再删除欺骗 - 所以这个代码是无效的(InventoryDetailsId 在 OPs 问题中是唯一的)
      • 需要比较的是其他字段,而不是InventoryDetailsId
      猜你喜欢
      • 2010-10-24
      • 2010-09-08
      • 1970-01-01
      • 2016-08-27
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 2011-04-19
      相关资源
      最近更新 更多