'Test whether the elements in two ranges are equal in C# using a lambda and LINQ
Is there a LINQ or C# method that helps to test whether the elements in two ranges are equal in C# using a lambda and LINQ.
In fact, I have 2 array of objects and I want to check if a property is the same on both array objects.
In C++, there's std::equal that can used with a lambda (example inspired from https://www.cplusplus.com/reference/algorithm/equal/)
// equal algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::equal
#include <vector> // std::vector
bool mypredicate (int i, int j) {
return (i==j);
}
int main () {
int myints[] = {20,40,60,80,100}; // myints: 20 40 60 80 100
std::vector<int>myvector (myints,myints+5); // myvector: 20 40 60 80 100
myvector[3]=81; // myvector: 20 40 60 81 100
// using predicate comparison:
if ( std::equal (myvector.begin(), myvector.end(), myints, [](int i, int j){ return i % 2 == 0 && j % 2 == 0; }) )
std::cout << "The contents of both sequences are equal.\n";
else
std::cout << "The contents of both sequences differ.\n";
return 0;
}
UPDATE: another C++ example that comes close to what I am trying to do:
#include <algorithm> // std::equal
#include <iostream> // std::cout
#include <string> // std::string
#include <vector> // std::vector
using namespace std;
struct Device
{
Device(string id) : id(id) {}
string id;
};
int main () {
Device mydevices[] = {Device("A1"), Device("A2")};
std::vector<Device> myvector(mydevices,mydevices+2);
mydevices[1].id = "B1";
// using predicate comparison:
if ( std::equal (myvector.begin(), myvector.end(), mydevices, [](Device i, Device j){ return i.id == j.id; }) )
std::cout << "The contents of both sequences are equal.\n";
else
std::cout << "The contents of both sequences differ.\n";
return 0;
}
Solution 1:[1]
You can use SequenceEqual:
int[] myints = {20,40,60,20,40};
IEnumerable<int> range1 = myints.Take(2);
IEnumerable<int> range2 = myints.Skip(3);
bool equalRanges = range1.SequenceEqual(range2); // true
If you need to compare object properties you have multiple options:
override
EqualsandGetHashCodeand use the code aboveimplement
IEquatable<YourObjectType>and use the code aboveimplement a custom
IEqualityComparer<YourObjectType>and use an instance of it as parameter forSequenceEqualand the code aboveUse a different LINQ query like this:
YourObjectType[] myobjects = {...}; IEnumerable<YourObjectType> range1 = myobjects.Take(2); IEnumerable<YourObjectType> range2 = myobjects.Skip(3); bool equalRanges = range1.Zip(range2, (x1, x2) => AreEqual(x1, x2)).All(b => b);
(where AreEqual is a method that compares the properties, you could do this inline as well)
Solution 2:[2]
You can use Zip to create an IEnumerable of tuples. With All you can check whether all of this tuples fulfill a condition:
Device[] devices1 = {new Device("A1"), new Device("A2")};
Device[] devices2 = {new Device("A1"), new Device("A2")};
if(devices1.Zip(devices2).All(x => x.Item1.ID == x.Item2.ID))
{
Console.WriteLine("devices1 and devices2 IDs are the same");
}
Online demo: https://dotnetfiddle.net/FIFOYP
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
