【问题标题】:Filter out duplicates from two lists and change object property value if duplicate从两个列表中过滤掉重复项,如果重复则更改对象属性值
【发布时间】:2018-05-10 10:20:44
【问题描述】:

我有两个列表 AuthorList 和 AuthorList2。目前我正在使用带有简单 IEqualityComparer 类的联合。 我希望有一个没有来自 AuthorList 和 AuthorList2 的重复项的结果列表,如果这些列表中有任何重复项,则需要将它们从列表中删除,并且需要将重复项的 Author 类 Assigned 属性设置为 true。

来自两个 AuthorLists 的现有信息:

ProductID 和分配

  • 1
  • 2,错误
  • 3,错误
  • 1

结果列表:

ProductID 和分配

  • 1
  • 2,错误
  • 3,错误

逻辑需要过滤掉重复项,如果这两个列表具有相同的元素,则更改 false -> true

namespace HelloWorld
{
     class Hello
      {
        static void Main()
        {

            List<Author> AuthorList = new List<Author>
            {
                new Author(1, false),
                new Author(2, false),
                new Author(3, false)
            };


            List<Author> AuthorList2 = new List<Author>
            {
                new Author(1, false)
            };

            var compareById = new AuthorComparer(false);

            var result = AuthorList.Union(AuthorList2, compareById);

            foreach (var item in result)
            {
                Console.WriteLine("Result: {0},{1}", item.ProductId, item.Assigned);
            }

            Console.ReadKey();
        }

        public class AuthorComparer : IEqualityComparer<Author>
        {
            private bool m_withValue;

            public AuthorComparer(bool withValue)
            {
                m_withValue = withValue;
            }

            public bool Equals(Author x, Author y)
            {
                return (x.ProductId == y.ProductId);
            }

            public int GetHashCode(Author x)
            {
                return x.ProductId.GetHashCode();
            }
        }

        public class Author
        {
            private int productId;
            private bool assigned;

            public Author(int productId, bool assigned)
            {
                this.productId = productId;
                this.assigned = assigned;
            }

            public int ProductId
            {
                get { return productId; }
                set { productId = value; }
            }

            public bool Assigned
            {
                get { return assigned; }
                set { assigned = value; }
            }
        }
      }
    }

【问题讨论】:

  • 那么您是要更新AuthorListAuthorList2 的元素吗?我怀疑一个简单的Intersect 电话在这里会有所帮助,但目前尚不清楚您期望什么结果......
  • 我正在尝试更新/过滤 AuthorList 的元素。我希望有一个没有任何重复项的列表,如果列表中有任何重复项,则需要将它们从列表中删除,并且 Author 类的 Assigned 属性需要设置为 true。
  • 顺便说一句,如果您使用自动实现的属性,您的 Author 类可能会简单得多:public int ProductId { get; set; } public bool Assigned { get; set; } - 并放弃字段。

标签: c# .net


【解决方案1】:

你要找的代码是这样的:

AuthorList.ForEach(a => a.Assigned = AuthorList2.Exists(b => b.ProductId == a.ProductId));

您根本不需要IEqualityComparer

完整的工作代码:

namespace HelloWorld
{
    class Hello
    {
        static void Main()
        {

            List<Author> AuthorList = new List<Author>
            {
                new Author(1, false),
                new Author(2, false),
                new Author(3, false)
            };


            List<Author> AuthorList2 = new List<Author>
            {
                new Author(1, false)
            };

            AuthorList.ForEach(a => a.Assigned = AuthorList2.Exists(b => b.ProductId == a.ProductId));

            foreach (var item in AuthorList)
            {
                Console.WriteLine("Result: {0},{1}", item.ProductId, item.Assigned);
            }

            Console.ReadKey();
        }

        public class Author
        {
            public Author(int productId, bool assigned)
            {
                this.ProductId = productId;
                this.Assigned = assigned;
            }

            public int ProductId { get; set; }

            public bool Assigned { get; set; }
        }
    }
}

【讨论】:

    【解决方案2】:

    使用您的比较器,您可以使用:

    foreach (var author in AuthorList.Intersect(AuthorList2, compareById))
    {
        author.Assigned = true;
    }
    

    如果您不需要比较器来做其他事情,您也可以轻松做到这一点:

    var author2Ids = new HashSet<int>(AuthorList2.Select(a => a.ProductId));
    foreach (var author in AuthorList.Where(a => author2Ids.Contains(a.ProductId)))
    {
        author.Assigned = true;
    }
    

    ...但是如果您需要比较器来做其他事情,或者它可能变得更复杂,我会坚持使用它。

    【讨论】:

      【解决方案3】:

      试试这样的东西。请仔细看!

             //Separate out different entries from both the lists
              var diffList = AuthorList.Where(x => !AuthorList2.Any(y => y.ProductId== x.ProductId && y.Assigned== x.Assigned)).ToList();
             //Separate out common entries from both the list
              var commonList = AuthorList.Where(x => AuthorList2.Any(y => y.ProductId== x.ProductId && y.Assigned== x.Assigned)).ToList();
              //Change value of Assigned
              commonList.ForEach(x => x.Assigned = !x.Assigned);
             //Merge both the lists
             diffList.AddRange(commonList);
      

      POC:DotNetFiddler

      【讨论】:

        【解决方案4】:

        这将产生一个新的元素列表而不改变源:

        private static List<Author> FilterDuplicates(List<Author> x, List<Author> y)
        {
             return x.Select(author => new Author(author.ProductId, y.Exists(a => a.ProductId == author.ProductId))).ToList();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-08-15
          • 2013-10-17
          • 2014-07-10
          • 1970-01-01
          • 2021-11-23
          • 2018-10-12
          • 2015-08-06
          相关资源
          最近更新 更多