none
Linq to make my code less than before RRS feed

  • Question

  • Here is  my code, I don’t want to use too much loop, could you help me try to use other ways to implement it.

    var person1 = new Person() { prodID = 1, Value = "foo", domainId = 0, Name = "red" };
    
               var person2 = new Person() { prodID = 1, Value = "bar", domainId = 0, Name = "Green" };
    
               var person3 = new Person() { prodID = 1, Value = "foo", domainId = 1, Name = "White" };
    
               var initialList = new List<Person>();
    
                initialList.Add(person1);
    
                initialList.Add(person2);
    
               var secondList = new List<Person>();
    
                secondList.Add(person3);
    
               List<Person> toRemove = new List<Person>();
    
               List<Person> toUpdate = new List<Person>();
    
               foreach (var per1 in initialList)
    
                {
    
                   foreach (var per2 in secondList)
    
                    {
    
                       if (per1.Value == per2.Value)
    
                        {
    
                           toRemove.Add(per1);
    
                            toUpdate.Add(per2);
    
                        }
    
                    }
    
                }
    
               foreach (var remPers in toRemove)
    
                {
    
                    initialList.Remove(remPers);
    
                }
    
     
    
               foreach (var updPers in toUpdate)
    
                {
    
                    initialList.Add(updPers);
    
                }
    
     
    
               foreach (var item in initialList)
    
                {
    
                   Console.WriteLine(String.Format("Value: {0}, prodId: {1}, domainId: {2}, Name: {3}", item.Value, item.prodID, item.domainId, item.Name));
    
    
                }

    Many thanks for your help

    Monday, November 14, 2016 12:18 PM

Answers

  • Try this:

    var person1 = new Person() { prodID = 1, Value = "foo", domainId = 0, Name = "red" };
    var person2 = new Person() { prodID = 1, Value = "bar", domainId = 0, Name = "Green" };
    var person3 = new Person() { prodID = 1, Value = "foo", domainId = 1, Name = "White" };
    
    var initialList = new List<Person> { person1, person2 };
    var secondList = new List<Person> { person3 };
    
    var query = from p1 in initialList
                from p2 in secondList
                where p1.Value == p2.Value
                select new { ToRemove = p1, ToAdd = p2 };
    
    var data = query.ToList();
    
    data.ForEach( d => initialList.Remove( d.ToRemove ) );
    initialList.AddRange( data.Select( d => d.ToAdd ) );
    
    initialList.ForEach( item => Console.WriteLine( String.Format( "Value: {0}, prodId: {1}, domainId: {2}, Name: {3}", item.Value, item.prodID, item.domainId, item.Name ) ) );



    • Edited by Viorel_MVP Monday, November 14, 2016 7:55 PM
    • Marked as answer by Kellyaaaaa2016 Tuesday, November 15, 2016 1:33 PM
    Monday, November 14, 2016 7:55 PM
  • Hi Kellyaaaaa,

    You also can use an IEqualityComparer<Person> which only compares the Value property like

    public class PersonValueComparer : IEqualityComparer<Person>
        {
            public bool Equals(Person x, Person y)
            {
               if(x==null&& y == null) { return true; }
                if (x == null || y == null) { return true; }
                return x.Value== y.Value;
            }
    
            public int GetHashCode(Person obj)
            {
                if(obj ==null || obj.Value == null) { return 0; }
                return obj.GetHashCode();
            }
        }

    Use Linq to query

      PersonValueComparer valueComparer = new PersonValueComparer();
                initialList = secondList.Where(p => initialList.Contains(p, valueComparer))
                      .Concat(initialList.Where(p => !secondList.Contains(p, valueComparer))).ToList();
    
              initialList.ForEach(item => Console.WriteLine(String.Format("Value: {0}, prodId: {1}, domainId: {2}, Name: {3}", item.Value, item.prodID, item.domainId, item.Name)));

    We are first using the Where() method to filter the secondList for items which are in the initialList . Then we use Concat() to add the Person's which are not in the secondList.

    Best regards,

    Kristin


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to  MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Edited by Kristin Xie Tuesday, November 15, 2016 1:49 AM
    • Marked as answer by Kellyaaaaa2016 Tuesday, November 15, 2016 1:33 PM
    Tuesday, November 15, 2016 1:47 AM

All replies

  • Try this:

    var person1 = new Person() { prodID = 1, Value = "foo", domainId = 0, Name = "red" };
    var person2 = new Person() { prodID = 1, Value = "bar", domainId = 0, Name = "Green" };
    var person3 = new Person() { prodID = 1, Value = "foo", domainId = 1, Name = "White" };
    
    var initialList = new List<Person> { person1, person2 };
    var secondList = new List<Person> { person3 };
    
    var query = from p1 in initialList
                from p2 in secondList
                where p1.Value == p2.Value
                select new { ToRemove = p1, ToAdd = p2 };
    
    var data = query.ToList();
    
    data.ForEach( d => initialList.Remove( d.ToRemove ) );
    initialList.AddRange( data.Select( d => d.ToAdd ) );
    
    initialList.ForEach( item => Console.WriteLine( String.Format( "Value: {0}, prodId: {1}, domainId: {2}, Name: {3}", item.Value, item.prodID, item.domainId, item.Name ) ) );



    • Edited by Viorel_MVP Monday, November 14, 2016 7:55 PM
    • Marked as answer by Kellyaaaaa2016 Tuesday, November 15, 2016 1:33 PM
    Monday, November 14, 2016 7:55 PM
  • Hi Kellyaaaaa,

    You also can use an IEqualityComparer<Person> which only compares the Value property like

    public class PersonValueComparer : IEqualityComparer<Person>
        {
            public bool Equals(Person x, Person y)
            {
               if(x==null&& y == null) { return true; }
                if (x == null || y == null) { return true; }
                return x.Value== y.Value;
            }
    
            public int GetHashCode(Person obj)
            {
                if(obj ==null || obj.Value == null) { return 0; }
                return obj.GetHashCode();
            }
        }

    Use Linq to query

      PersonValueComparer valueComparer = new PersonValueComparer();
                initialList = secondList.Where(p => initialList.Contains(p, valueComparer))
                      .Concat(initialList.Where(p => !secondList.Contains(p, valueComparer))).ToList();
    
              initialList.ForEach(item => Console.WriteLine(String.Format("Value: {0}, prodId: {1}, domainId: {2}, Name: {3}", item.Value, item.prodID, item.domainId, item.Name)));

    We are first using the Where() method to filter the secondList for items which are in the initialList . Then we use Concat() to add the Person's which are not in the secondList.

    Best regards,

    Kristin


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to  MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Edited by Kristin Xie Tuesday, November 15, 2016 1:49 AM
    • Marked as answer by Kellyaaaaa2016 Tuesday, November 15, 2016 1:33 PM
    Tuesday, November 15, 2016 1:47 AM