Determine if two arrays are structurally equal in C# .NET

Two arrays are said to be structurally equal if they contain the same elements in the same order. Whether or not two elements are the same depends on how you define equality for your custom types. Equality for primitive types, like integers, is more or less straightforward but you’ll need to declare in code what is meant by equality for reference types.

We’ve looked at a couple of strategies to do so on this blog and here we’ll re-use the topic of implementing the IEqualityComparer of T interface.

The non-generic IStructuralEquatable interface has an equals method that accepts an object to compare with and another object which implements the non-generic IEqualityComparer interface. This is an important distinction as implementing the generic IEqualityComparer interface won’t be enough for structural equality. We’ll need to derive from the EqualityComparer base class which implements both the generic and non-generic version of IEqualityComparer. If you try to run the below example with a generic IEqualityComparer of T instance then you’ll get a compiler error.

Note that structural equality is not available for all collection types. Currently only arrays and tuples support it, i.e. they can be cast to type IStructuralEquatable. However, as List objects can be easily converted into arrays that’s not really an obstacle.

Consider the following Triangle class:

public class Triangle
{
	public double BaseSide { get; set; }
	public double Height { get; set; }
}

Let’s say that two triangles are equal if their bases and heights are the same. We’ll implement our equality comparer accordingly. As noted above we need to derive from the EqualityComparer

public class TriangleSideEqualityComparer : EqualityComparer<Triangle>
{	
	public override bool Equals(Triangle x, Triangle y)
	{
		return (x.BaseSide == y.BaseSide && x.Height == y.Height);
	}

	public override int GetHashCode(Triangle obj)
	{
		return (obj.BaseSide.GetHashCode() * obj.Height.GetHashCode());
	}
}

Now consider the following collections:

List<Triangle> triangleListOne = new List<Triangle>()
{
	new Triangle(){BaseSide = 2, Height = 4},
	new Triangle(){BaseSide = 4, Height = 5},
	new Triangle(){BaseSide = 5, Height = 9},
	new Triangle(){BaseSide = 3, Height = 8}
};

List<Triangle> triangleListTwo = new List<Triangle>()
{
	new Triangle(){BaseSide = 2, Height = 4},
	new Triangle(){BaseSide = 4, Height = 5},
	new Triangle(){BaseSide = 5, Height = 9},
	new Triangle(){BaseSide = 3, Height = 8}
};

The two lists are clearly structurally equal as they store equal Triangle instances where the triangles appear in the same order. Here’s a possible solution to the problem:

IStructuralEquatable equatableOne = triangleListOne.ToArray();
bool areStructurallyEqual = equatableOne.Equals(triangleListTwo.ToArray(), new TriangleSideEqualityComparer());

areStructurallyEqual will be true. As soon as we change just a single parameter in any of the triangles then this function will result in false.

View all various C# language feature related posts here.

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Love to use Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Ricos Blog zu Softwaredesign- und architektur

Ideen und Gedanken rund um Softwaredesign und -architektur, Domain-Driven Design, C# und Windows Azure

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: