【问题标题】:Getting a value from a List in a List of objects C#从对象列表中的列表中获取值C#
【发布时间】:2018-06-22 12:03:27
【问题描述】:

我有一个 class object(obj1)List,并且该类包含另一个 List 的另一个 class object(obj2)。以下是我的代码:

public List<Class1> Obj1{ get; set; }

 public class Class1
    {
        [DataMember]
        public int Class1Id { get; set; }
        [DataMember]
        public string Class1Desc { get; set; }
        [DataMember]
        public List<Class2> obj2{ get; set; }
    }

public class Class2
    {
        [DataMember]
        public int Class2Id { get; set; }
        [DataMember]
        public string Class2Desc { get; set; }
    }

现在,我需要填充变量以确保不会得到重复值(即 Class1IdClass2Id 的组合应该是唯一的)。

我不想使用循环。我怎样才能做到这一点?

【问题讨论】:

  • 您可以使用您在 Class1 中制作的某种方法单独设置它们
  • 你可以使用Hashset&lt;Class2&gt; ?
  • “现在,我需要填充变量” - 哪些变量?班上的那些?如果是这样,您的数据来源是什么?或者您是否从 Obj1 列表中填充其他变量,在这种情况下您要填充哪些变量以及使用哪些数据?
  • 这是一个衬里:var result = Obj1.SelectMany(x=> x.obj2.Select(y=> new {x,y})).GroupBy(t=> new {txClass1Id, tyClass2Id}).Select(x=> x.First()).ToList();
  • 你能举个例子吗?你觉得标题合适吗?你认为正则表达式相关吗?

标签: c# .net regex linq


【解决方案1】:

使用IEquatable,然后使用Distinct()

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication52
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Class1> Obj1 = new List<Class1> {
                new Class1() { Class1Desc = "A", Class1Id = 1, obj2 = new List<Class2>() { new Class2() { Class2Id = 100, Class2Desc= "M"}}},
                new Class1() { Class1Desc = "B", Class1Id = 1, obj2 = new List<Class2>() { new Class2() { Class2Id = 100, Class2Desc= "M"}}},
                new Class1() { Class1Desc = "A", Class1Id = 1, obj2 = new List<Class2>() { new Class2() { Class2Id = 100, Class2Desc= "M"}}},
                new Class1() { Class1Desc = "A", Class1Id = 1, obj2 = new List<Class2>() { new Class2() { Class2Id = 200, Class2Desc= "M"}}}
            };

            List<Class1> distinctClass1 = Obj1.Distinct().ToList();
        }
    }
    public class Class1 : IEquatable<Class1>
    {
        public int Class1Id { get; set; }
        public string Class1Desc { get; set; }
        public List<Class2> obj2 { get; set; }

        public Boolean Equals(Class1 other)
        {

            if (other == null) return false;
            if ((this.Class1Id == other.Class1Id) && (this.Class1Desc == other.Class1Desc) && (this.obj2.OrderBy(x => x).SequenceEqual(other.obj2.OrderBy(x => x))))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public override int GetHashCode()
        {
            return (this.Class1Id.ToString() + "^" + this.Class1Desc + string.Join("^", obj2.Select(x => x.GetHashCodeStr()))).GetHashCode();
        }

    }

    public class Class2 : IEquatable<Class2> , IComparer<Class2>
    {
        public int Class2Id { get; set; }
        public string Class2Desc { get; set; }

        public Boolean Equals(Class2 other)
        {
            if(other == null) return false;
            if ((this.Class2Id == other.Class2Id) && (this.Class2Desc == other.Class2Desc))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public int Compare(Class2 x, Class2 y)
        {
            int results = 0;
            results = x.Class2Id.CompareTo(y.Class2Id);
            if (results == 0)
            {
                results = x.Class2Desc.CompareTo(y.Class2Desc);
            }
            return results;
        }
        public override int GetHashCode()
        {
            return (this.Class2Id.ToString() + "^" + this.Class2Desc).GetHashCode();
        }
        public string GetHashCodeStr()
        {
            return this.Class2Id.ToString() + "^" + this.Class2Desc;
        }

    }
}

【讨论】:

  • 我认为您可能需要实现的不仅仅是 IEquatable 以使 Distinct 工作 - 我相信 GetHashCode 也将需要。 Distinct() 将创建一个 EqualityComparer&lt;T&gt;.Default,它依赖于 GetHashCode 我相信。至少你的代码对我不起作用,我认为这就是原因。
  • 如何处理 "确保我没有得到重复值(即 Class1IdClass2Id 的组合应该是唯一的)”?我猜一个Class1 实例是另一个Class1 实例的副本,如果两者都有相交的new[]{Class1Id}.Union(obj2.Select(x=&gt;x.Class2Id)) 整数。但也许所有整数都必须相同,而不仅仅是一个。
  • 我很惊讶没有使用 GetHashCode() 编译的代码没有错误。你真的不需要哈希码,你可以把哈希返回 0 ,它会工作。 IEquatable 调用 GetHashCode 以首先检查项目是否相等,然后在哈希不相等时调用 Equal 方法。如果您只是比较 A(而不是 ),为什么要创建一个不需要的哈希。我相信它使用标准的 List GetHashCode 作为默认值。通常你使用 GetHashCode() 覆盖。
  • @Tim Schmelter : IEquatable 处理重复项。我的代码假定第一类和第二类中的所有对象都必须相同。这些类是列表对象,因此标准 List Equal 用作比较的基类。
  • @jdweng: ideone.com/XRv0dr 是您的代码的精简版(删除了第 2 类)。它似乎没有检测到添加到列表中的重复对象(应该有 10 个不同的对象,并且 Equals 中的 Console.WriteLine 似乎永远不会被调用)。 (我不认为我在削减你的代码方面搞砸了)。
猜你喜欢
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多