2

I have 2 lists with objects. I want to compare them and return all the NEW objects in new list

I try below code, but I don't get answered

 var inInsyt = (from prd in db.COM_CUSTOMER_PRODUCT
                 join inv in db.INS_INVENTORY on prd.COM_CUSTOMER_PRODUCT_ID 
                 equals inv.COM_PRODUCT_ID
                 where prd.COM_CUSTOMER_ID == 5252
                 select new ProductInventoryInfo
                 {
                     sku = prd.PRODUCT_CODE,
                     quantity = inv.INV_AVAILABLE
                 }).ToList();


            var inEComSite = (from qlInv in db.INS_OPENCART_QOOLMART_INVENTORY
                              where qlInv.ID>0
                              select new ProductInventoryInfo
                              {
                                  sku = qlInv.SKU,
                                  quantity = qlInv.QUANTITY
                              }).ToList();

---------1st method----------------------------------------------------------------------------

            var firstNotSecond = inInsyt.Except(inEComSite).ToList();
            var secondNotFirst = inEComSite.Except(inInsyt).ToList();

--------------------2nd method-----------------------------------------------------------

 List<ProductInventoryInfo> objectList3 = inEComSite.Where(o => inInsyt.Contains(o)).ToList();

 List<ProductInventoryInfo> objectList4 = inInsyt.Where(o => !inEComSite.Contains(o)).ToList();

Ram
  • 25
  • 5
  • 1
    If you want to compare sequences of objects of some custom data type, you have to implement the IEquatable generic interface in a helper class. [DOCS](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DEN-US%26k%3Dk(System.Linq.Enumerable.Except%60%601);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.6.1);k(DevLang-csharp)%26rd%3Dtrue&view=netframework-4.8) – Luuk Nov 30 '19 at 11:14
  • Please check below I submitted an answer – Ram Nov 30 '19 at 12:23

4 Answers4

3

You should implement an IEqualityComparer for your ProductInventoryInfo class.

Take a look here

Corentin Pane
  • 4,794
  • 1
  • 12
  • 29
Peter Schneider
  • 2,879
  • 1
  • 14
  • 17
1

If you have two lists of strings or numbers, you can use the following methods to compare

Main Method

var list1 = new List<string>
        {
            "Product 1",
            "Product 2",
            "Product 3",
            "Product 4"
        };

var list2 = new List<string>
        {
            "Product 2",
        };

var list3 = list1.Where(i => list2.All(x => x != i)).ToList();

var list4 = list1.Except(list2).ToList();

If two lists are objecs you can use the following methods to compare

class ProductInventoryInfo

public class ProductInventoryInfo
{
    public string ProductName { get; set; }

    public override bool Equals(object obj)
    {
        if (!(obj is ProductInventoryInfo))
        {
            return false;
        }

        var other = (ProductInventoryInfo)obj;
        return this.ProductName == other.ProductName;
    }

    protected bool Equals(ProductInventoryInfo other)
    {
        return ProductName == other.ProductName;
    }

    public override int GetHashCode()
    {
        return (ProductName != null ? ProductName.GetHashCode() : 0);
    }
}

Extensions Method to compare objects

public static class ExtensionsMethod
{
    public static bool ObjectsAreEqual(this IEnumerable<ProductInventoryInfo> items, ProductInventoryInfo obj2)
    {
        return items.Any(productInventoryInfo => ObjectsAreEqual<ProductInventoryInfo>(productInventoryInfo, obj2));
    }

    private static bool ObjectsAreEqual<T>(T obj1, T obj2)
    {
        return JsonConvert.SerializeObject(obj1) == JsonConvert.SerializeObject(obj2);//convert object to json by Newtonsoft.Json and compare that
    }
}

Main Method

 var list1 = new List<ProductInventoryInfo>
        {
            new ProductInventoryInfo{ ProductName="Product 1"},
            new ProductInventoryInfo{ ProductName="Product 2"},
            new ProductInventoryInfo{ ProductName="Product 3"},
            new ProductInventoryInfo{ ProductName="Product 4"},
        };

 var list2 = new List<ProductInventoryInfo>
        {
            new ProductInventoryInfo{ ProductName="Product 2"},
        };

 var list3 = list1.Where(x => !list2.ObjectsAreEqual(x)).ToList(); //use Extensions Method

 //use override Equals
 var list4 = new List<ProductInventoryInfo>();

 list1.ForEach(x =>
     {
       list2.ForEach(y =>
          { 
            if (!x.Equals(y))
              {
                 list4.Add(x);
              }
          });
      });
Reza Jenabi
  • 3,884
  • 1
  • 29
  • 34
0

See the below snippet:

        List<int> firstList = new List<int>() { 1,2,2,3,3 };
        List<int> secondList = new List<int>() { 1 };
        List<int> newList = new List<int>();

        var firstNotSecond = firstList.Except(secondList).ToList();
        var secondNotFirst = secondList.Except(firstList).ToList();

        newList.AddRange(firstNotSecond);
        newList.AddRange(secondNotFirst);

output newList: {2,3}

Hamid
  • 11
  • 2
  • Thanks for your response, sorry, i tried above method but I got wrong answer – Ram Nov 30 '19 at 11:28
  • This works perfectly if you add objects to lists from same type.(( var differences = list2.Where(l2 => !list1.Any(l1 => l1.sku == l2.sku && l1.quantity == l2.quantity )); )) – Ram Nov 30 '19 at 12:12
0

This works perfectly if you add objects to lists from same type

var differences = list2.Where(l2 => 
    !list1.Any(l1 => l1.sku == l2.sku && l1.quantity == l2.quantity ));

Or(If you prefer)

 var differences = list2.Where(l2 => 
        !list1.Any(l1 => l1.sku == l2.sku || l1.quantity == l2.quantity ));
Ram
  • 25
  • 5