从两个列表中筛选出重复项,如果重复则更改对象属性值

时间:2018-05-10 10:20:45

标签: c# .net

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

来自两个作者列表的现有信息:

ProductID&分配

  • 1 false
  • 2,false
  • 3,false
  • 1 false

结果列表:

ProductID&分配

  • 1 true
  • 2,false
  • 3,false

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

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; }
            }
        }
      }
    }

4 个答案:

答案 0 :(得分:0)

您正在寻找的代码是:

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; }
        }
    }
}

答案 1 :(得分:0)

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

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;
}

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

答案 2 :(得分:0)

尝试这样的事情。请仔细查看!

       //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

答案 3 :(得分:0)

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

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();
}