【问题标题】:looping through to get duplicates in an object C#循环获取对象C#中的重复项
【发布时间】:2019-07-18 10:20:51
【问题描述】:

我有一个对象的对象,其中一个属性可以具有重复值我正在尝试找到一种算法来循环遍历该对象并创建一个具有按重复值分组的新对象列表。

我如何遍历一个对象并在 C# 中创建一个新对象我有一个视图模型,例如:

   pViewModel  {
    public itemFullName {get;set;}
    public Item Item{get;set;}
    public string itemAddress {get;set;}
    public string itemCountry {get;set;}
public string addressId {get;set;}
    }
    public Item{
    public int itemId{get;set;}
    }

我想在找到匹配的全名但不同的 id 后创建一个新对象,因此我的新对象将包含 itemFullName、item.itemid(上一个列表中所有项目的管道分隔值)、itemaddress、itemCountry 的列表。

任何帮助都会很棒。谢谢

有人指出了这一点

var itemsAndIds = list
    .GroupBy(m => m.itemFullName, m => m.Item.itemId)
    .Select(g => new {ItemFullName = g.Key, ItemIds = string.Join("|", g)})

但现在我需要添加到这个对象的新属性

【问题讨论】:

  • 对于分组的 itemid,ItemAddress 和 ItemCountry 是否相同或不同。如果不同,那么应该如何在新对象中选择它们?
  • 所有重复值都相同
  • 如果有一个与上述列表不同的属性,例如。 addressId ,如何以逗号分隔值在分组列表中返回?

标签: c# asp.net asp.net-mvc linq grouping


【解决方案1】:

这个答案可以帮助你: https://stackoverflow.com/a/5232194/1341189

鉴于 ItemAddress 和 ItemCountry 在您的示例中始终与 ItemFullName 相同,这意味着您可以执行以下操作:

var itemsAndIds = list
    .GroupBy(m => new { 
               ItemFullName = m.itemFullName, 
               ItemAddress = m.itemAddress, 
               ItemCoutnry = m.itemCountry },
             m => m.Item.itemId)
    .Select(g => new {
              ItemFullName = g.Key.ItemFullName, 
              ItemIds = string.Join("|", g),
              ItemAddress = g.Key.ItemAddress,
              ItemCoutnry = g.Key.ItemCountry})

另外,我想建议您阅读 Microsoft 命名约定。

属性名称应该用 PascalCase 编写(类名称也是如此)。 https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members

【讨论】:

  • 如果有一个与上述列表不同的属性,例如。 addressId ,如何以逗号分隔值在分组列表中返回?
  • @user1098924 您还可以在 groupBy 的第二部分中包含更多属性,如下所示:m => new { ItemId = m.Item.itemId, AddressId = m.addressId } 然后您必须像这样使用它们:ItemIds = string.Join("|", g.Select(gs => gs.ItemId)), AddressIds = string.Join("|", g.Select(gs => gs.AddressId).Distinct()), PS:如果您只想使用 Distinct在分开的地址 ID 列表中获取不同的地址 ID
【解决方案2】:

您可以覆盖对象中的bool Equals(Object obj) 方法。这样,您可以按整个项目分组,然后只选择新项目。您将把比较逻辑密封在您的对象中,您可以轻松地使用内置机制,如 == 比较或整个 linq 魔法,而无需任何黑客攻击。这样你的类就完全符合 SOLID 原则了

请记住,如果你重写 Equals,为了保持一致性,重写 int GetHashCode() 方法也是值得的。这样您就可以保持比较的一致性(确切地说,您需要确保游览实施遵循这三个主要规则):

  • a == a 和 a.Equals(a) 应始终为真(自反性)。
  • a == b、b == a、a.Equals(b) 和 b.Equals(a) 应始终给出相同的结果。 (对称)
  • 如果 a == b 为真且 b == c 为真,则 a == c 也应为真(传递性)。这同样适用于 a.Equals(b)、b.Equals(c) 和 a.Equals(c)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    相关资源
    最近更新 更多