0

I am having trouble comparing two lists using Linq.
My first list contains object instances, which contain a property of interest, to be compared against a second list that contains only values.
Say we have:

List<uint> referenceValues = new List<uint>(){1, 2, 3};
and
List<SomeObject> myObject= new List<SomeObject>();

Now the SomeObject() class has the property "Value" of type uint.
Note that "myObject" list may contains more elements than the "referenceValues" list and we therefore have to select the appropriate portion of "myObject" to be compared against "referenceValues".

I have found the following stack overflow question, which is related, but not quite what I am after: link

Here is what I have tried so far, but without success:

if (myObject
    .GetRange((int)offset, count)       // Extracted the object of interest from the list
    .Where(x => referenceValues.Equals(x.Value)).Count() == 0)   // Comparing the "Value" properties against the "referenceValues"
{
    // Do something
}

I think I need to use "SequenceEqual" somehow, but I am not really getting how to.
Any advice would be very welcome.

EDIT

Reproducible example:

using System;
using System.Linq;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        int offset = 0;
            
        List<uint> referenceValues = new List<uint>(){1, 2, 3};

        List<SomeObject> myObject= new List<SomeObject>(){new SomeObject(){Value=1}, 
                                                          new SomeObject(){Value=2},
                                                          new SomeObject(){Value=3}};
        
        if (myObject
            .GetRange(offset, referenceValues.Count()-1)       // Extracted the object of interest from the list
            .Where(x => referenceValues.Equals(x.Value)).Count() == referenceValues.Count())   // Comparing the "Value" properties against the "referenceValues"
        {
            // Do something
            Console.WriteLine("Lists are matching!");
        }
        else
        {
            Console.WriteLine("Lists are not matching!");
        }
    }
}

public class SomeObject
{
    public uint Value = 0;
}

EDIT2

Working solution as per suggestion from Guru Stron:

using System;
using System.Linq;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        int offset = 0;
            
        List<uint> referenceValues = new List<uint>(){1, 2, 3};

        List<SomeObject> myObject= new List<SomeObject>(){new SomeObject(){Value=1}, 
                                                          new SomeObject(){Value=2},
                                                          new SomeObject(){Value=3}};
        
        if (myObject.
            GetRange((int)offset, referenceValues.Count())   
            .Select(someObject => someObject.Value)
            .SequenceEqual(referenceValues))
        {
            // Do something
            Console.WriteLine("Lists are matching!");
        }
        else
        {
            Console.WriteLine("Lists are not matching!");
        }
    }
}

public class SomeObject
{
    public uint Value = 0;
}

Recommended book about Linq expressions: LINQ Pocket Reference

stackMeUp
  • 522
  • 4
  • 16

2 Answers2

1

If you want to check if some subset of myObject values has some concrete order by some property you can do something like this:

bool inOrder = myObject
    .GetRange((int)offset, count)   
    .Select(someObject => someObject.Value)
    .SequenceEqual(referenceValues);

If you want to just check that all values are present in the specified referenceValues you can use All (also if source range is empty this returns true):

bool allPresent = myObject
    .GetRange((int)offset, count)   
    .All(someObject => referenceValues.Contains(someObject.Value));

For full collection match without ordering I don't know out of box solution but you can look for one for example here.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • Thanks a lot, I think this is working :-) Do you have a good tutorial about LINQ to recommend? I am always struggling with that. – stackMeUp Oct 21 '20 at 15:19
  • But the second option will not care about order? – stackMeUp Oct 21 '20 at 15:25
  • 1
    @stackMeUp was glad to help. You can look [here](https://stackoverflow.com/a/6018401/2501279) for some recommendations. When I was starting using LINQ `LINQ Pocket Reference` by Albahari proved to be useful for me. – Guru Stron Oct 21 '20 at 15:26
  • 1
    @stackMeUp second one will not, it will just check that all values in the collection exist in `referenceValues` (but not vice versa, there maybe missing entries from `referenceValues` in `myObject.Range`). – Guru Stron Oct 21 '20 at 15:28
  • Nice one! It might become handy elsewhere! – stackMeUp Oct 21 '20 at 15:29
  • 1
    @stackMeUp again - was glad to help. Read the reviews first, maybe it will not be as useful for you as it was for me. People are different) – Guru Stron Oct 21 '20 at 15:29
0
if(myObject.Any(x => referenceValues.Contains(x.Value)) {}

I ignored the GetRange part but should make no difference.

Ralf
  • 1,216
  • 10
  • 20