0

I am trying to compare two lists of objects in C# and return a new list that contains only the items that match certain criteria. Each list contains objects with the following structure:

public class MyObject
{
    public string Name { get; set; }
    public int Value { get; set; }
    public bool IsActive { get; set; }
}

I want to compare the Name and Value properties of each object in both lists, and return a new list of objects that meet the following criteria:

  • The Name property of the object in list1 is equal to the Name property of the object in list2.
  • The Value property of the object in list1 is greater than the Value property of the object in list2.

I have tried using LINQ's Where method and Join clauses, but I am having trouble getting the desired results. Here is the code I have so far:

var results = list1.Where(x => x.Name == list2.Where(y => y.Name).FirstOrDefault() &&
                               x.Value > list2.Where(y => y.Value).FirstOrDefault());

This code is only returning a list of the first object in list1 that meets the criteria, rather than a list of all matching objects. Can you help me understand what is going wrong and suggest a solution to get the desired results?

Thank you in advance for your help!

3
  • can you try this : var results = list1.Where(x => list2.Any(y => y.Name == x.Name && y.Value < x.Value)).ToList(); Commented Jan 3, 2023 at 19:01
  • join or intersect with custom comparer Commented Jan 3, 2023 at 19:19
  • Are the lists sharing the objects? or are the instances different but same content. Commented Jan 3, 2023 at 20:42

1 Answer 1

3

How about using a Join to match the name between list1 and list2, then filtering for greater value with a Where, finally selecting the unique (distinct) items from list1?

void Main()
{
    var list1 = new List<MyObject> { 
        new MyObject { Name = "A", Value = 2 },
        new MyObject { Name = "A", Value = 1 },
        new MyObject { Name = "B", Value = 1 } 
    };

    var list2 = new List<MyObject> {
        new MyObject { Name = "A", Value = 2 },
        new MyObject { Name = "A", Value = 1 },
        new MyObject { Name = "C", Value = 1 }
    };

    var result = list1
        .Join(list2, l1 => l1.Name, l2 => l2.Name, (l1, l2) => new {l1, l2})
        .Where(x => x.l1.Value > x.l2.Value)
        .Select(x => x.l1)
        .Distinct()
        .ToList();

    result.ForEach(r => Console.WriteLine($"Name:{r.Name} Value:{r.Value} IsActive:{r.IsActive}"));
    
}

public class MyObject
{
    public string Name { get; set; }
    public int Value { get; set; }
    public bool IsActive { get; set; }
}

This returns items from list1 with name matches in list2 where the value of list1 is greater than the value in list2:

Name:A Value:2 IsActive:False

Sign up to request clarification or add additional context in comments.

2 Comments

what is the expected result if you replace 2 by 3 in the first line for list1?
@MohammedSajid That is a good question. I think you might want to add .Distinct() after the Select clause to make sure only unique values of list1 are returned. I've updated my post above to reflect that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.