Comparing Arrays in C#

Easiest way to compare arrays in C#

You could use Enumerable.SequenceEqual. This works for any IEnumerable<T>, not just arrays.

Comparing two arrays in C#

Since this is Homework, I will give you a homework answer.

Sure, you could use LINQ and rely on SequenceEqual, Intersect, etc, but that is likely not the point of the exercise.

Given two arrays, you can iterate over the elements in an array using foreach.

int[] someArray;
foreach(int number in someArray)
{
//number is the current item in the loop
}

So, if you have two arrays that are fairly small, you could loop over each number of the first array, then loop over the all the items in the second array and compare. Let's try that. First, we need to correct your array syntax. It should look something like this:

    int[] a = new int[] {1, 2, 3, 4};
int[] b = new int[] { 5, 6, 1, 2, 7, 8 };

Note the use of the curly braces {. You were using the syntax to create a N-dimensional array.

bool hasDuplicate = false;
int[] a = new int[] { 1, 2, 3, 4 };
int[] b = new int[] { 5, 6, 7, 8 };
foreach (var numberA in a)
{
foreach (var numberB in b)
{
//Something goes here
}
}

This gets us pretty close. I'd encourage you to try it on your own from here. If you still need help, keep reading.


OK, so we basically need to just check if the numbers are the same. If they are, set hasDuplicate to true.

bool hasDuplicate = false;
int[] a = new int[] { 8, 1, 2, 3, 4 };
int[] b = new int[] { 5, 6, 7, 8 };
foreach (var numberA in a)
{
foreach (var numberB in b)
{
if (numberA == numberB)
{
hasDuplicate = true;
}
}
}

This is a very "brute" force approach. The complexity of the loop is O(n2), but that may not matter in your case. The other answers using LINQ are certainly more efficient, and if efficiency is important, you could consider those. Another option is to "stop" the loops using break if hasDuplicate is true, or place this code in a method and use return to exit the method.

Compare Arrays in C# using SequenceEqual

Using @Sweeper/@Jeppe Stig Nielsen suggestions, I rewrote my function as:

public bool Equals(VRValue<T> other)
{
if (typeof(T).IsArray)
{
var first = Value as IStructuralEquatable;
var second = other.Value as IStructuralEquatable;
return StructuralComparisons.StructuralEqualityComparer.Equals(first, second);
}
[...]
}

When using a HashSet, one should also pay attention to GetHashCode:

public override int GetHashCode()
{
if (typeof(T).IsArray)
{
var first = Value as IStructuralEquatable;
return StructuralComparisons.StructuralEqualityComparer.GetHashCode(first);
}
[...]
}

Compare Two Arrays And Delete Same (Intersect) Value From Second Array

Just use, Where, Contains, in a Linq statement then ToArray

In simple terms,

  1. It filters array two by checking if array one does not contain each element of two

  2. Converts the output back to an array

  3. Assigns its back to your variable two

Example

string[] one={"my", "5", "two", "array", "hey?", "good", "day"};
string[] two = { "hello!", "how", "good", "day", "us", "very", "two", "hard", "learn", "it" };

two = two.Where(x => !one.Contains(x)).ToArray();

Console.WriteLine(string.Join(",", two));

Note, This is case sensitive

Output

hello!,how,us,very,hard,learn,it

Or a more performant way is to use Except, which i totally forgot about (thanks to comments)

two = two.Except(one).ToArray();

Enumerable.Except Method

Produces the set difference of two sequences.

Enumerable.Where Method

Filters a sequence of values based on a predicate.

Enumerable.Contains Method

Determines whether a sequence contains a specified element.

Enumerable.ToArray(IEnumerable) Method

Creates an array from a IEnumerable.

comparing two int arrays and printing out the difference

You can try to use linq Except to get different from two arrays, then use Union combine two arrays.

var result1 = arr2.Except(arr1);
var result2 = arr1.Except(arr2);
var result = result1.Union(result2);

c# online

Comparing two arrays in a generic .Equals method

Part of the problem is that field.GetValue(other) returns an object. You'll likely find that using recursive reflection to compare untyped objects will frustrate you.

In order to make this work you'd have to determine whether the field is a collection, and if it is, compare the contents of the collection instead. Then what if one of collections contains a collection? This is doable, but it's a headache.

Whatever this object is that you're trying to compare, it's much simpler if you implement IEquatable<T> or define an IEqualityComparer<T> for the types you want to compare. Your Equals method then checks equality explicitly for the various members. If those members are reference types, you define equality for those as well. Then, if those types have more nested properties you don't have drill down into all of those nested properties and compare their properties.

What this ultimately requires is that your method "knows" what types it's comparing so that it knows exactly how to compare them. If you're using reflection to figure out what the properties are and then trying to check them for equality, it's possible, but it's difficult and potentially broken by future changes.

Here's an example using a few classes with nested properties.

public class Foo : IEquatable<Foo>
{
public int FooValue { get; set; }
public List<Bar> Bars { get; set; }

public bool Equals(Foo other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
if (FooValue != other.FooValue) return false;
if (Bars == null ^ other.Bars == null) return false;
return Bars == null || Bars.SequenceEqual(other.Bars);
}
}

public class Bar : IEquatable<Bar>
{
public int BarValue { get; set; }
public List<FooBar> FooBars { get; set; }

public bool Equals(Bar other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
if( BarValue != other.BarValue) return false;
if (FooBars == null ^ other.FooBars == null) return false;
return FooBars==null || FooBars.SequenceEqual(other.FooBars);
}
}

public class FooBar : IEquatable<FooBar>
{
public int FooBarValue { get; set; }

public bool Equals(FooBar other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return FooBarValue == other.FooBarValue;
}
}

Each class with a nested collection property uses SequenceEqual to determine whether the collections match. But how does it figure out whether individual items in those collections are equal to each other? It doesn't. It assumes that those types will be able to to determine equality.

Now if the conditions that make two instances of a class equatable change, the details can be isolated to that class.

Suppose I can't modify one of these classes to support IEquatable<T>, or for some reason it doesn't make sense to. Perhaps equality is determined differently in different contexts. Maybe a class has an ID property and in some context all I care about is that if two objects have the same ID, they're equal.

In that case I could move that equality comparison into its own class and only use it when I want to. It's no longer "built in" to the class.

public class FooBar 
{
public int FooBarValue { get; set; }
}

public class FooBarComparer : IEqualityComparer<FooBar>
{
public bool Equals(FooBar x, FooBar y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
return x.FooBarValue == y.FooBarValue;
}

public int GetHashCode(FooBar obj)
{
return obj.GetHashCode();
}
}

Now when I use SequenceEqual on two collections of FooBar I would do this:

FooBars.SequenceEqual(other.FooBars, new FooBarComparer())

Another benefit of this is that you can re-use equality comparisons. Suppose you have two different classes with a list of Bar. Now both classes don't have to inspect Bar and its nested properties to determine equality, which would duplicate code. That equality check is located elsewhere and can be shared by both when that's desirable.

How to compare values in one array?

The problem is in the upper bound check in your for loop. When i = ipp.Length - 1 and you access array item ipp[i + 1] you access an element outside of the array bounds, therefore the problem occurs.

You need to change upper bound check to the i < ipp.Length - 1:

for (int i = 0; i < ipp.Length - 1; i++)
{
if (ipp[i + 1] > ipp[i])
{
...
}
}


Related Topics



Leave a reply



Submit