SameOldNick
SameOldNick

Reputation: 2457

Getting the number of elements that are the same at the same index

I have two arrays (both the same length) and I'm trying to iterate through each element in both arrays and test if those elements (that have the same index) are equal or not. I want to get the number that are equal and the number that are not equal. I have been able to do it using a while loop, but I'm wondering if there's a quicker way with the System.Linq extensions?

Here's what I have right now:

    var list1 = new List<Color>
        {
            Color.Aqua,
            Color.AliceBlue,
            Color.Beige,
            Color.Red,
            Color.Green,
            Color.White
        };


        var list2 = new List<Color>
        {
            Color.Red,
            Color.BurlyWood,
            Color.Beige,
            Color.Azure,
            Color.Green,
            Color.Magenta
        };

        var enumFirst = list1.GetEnumerator();
        var enumSecond = list2.GetEnumerator();

        var equal = 0;
        var notEqual = 0;

        while (enumFirst.MoveNext() && enumSecond.MoveNext())
        {
            var colorFirst = enumFirst.Current;
            var colorSecond = enumSecond.Current;

            if (colorFirst == colorSecond)
                equal++;
            else
                notEqual++;
        }

        Console.WriteLine("Elements that are equal: " + equal);
        Console.WriteLine("Elements that are not equal: " + notEqual); 

The output is:

Elements that are equal: 2
Elements that are not equal: 4

Upvotes: 4

Views: 752

Answers (2)

Kamil Budziewski
Kamil Budziewski

Reputation: 23107

Maybe not quicker, but definitely one-liner:

var areequal = list1.Select((x, i) => list2[i] == x);
var equals = areequal.Count(x => x);
var notequals = areequal.Count(x => !x);

Using Select you can select if elemest are equal or not, and then by using count, count each group. This method will work only if list2 is at least same size as list1 (but in question is note that lists are same size)

But if in some case these lists are of different size change first line to:

var areequal = list1.Take(Math.Min(list2.Count, list.Count))
                                                      .Select((x, i) => list2[i] == x);

Take will make you sure that all processed elements from list1 are the same size as list2.

Upvotes: 2

MarcinJuraszek
MarcinJuraszek

Reputation: 125640

Yes, use Zip.

var equal = list1.Zip(list2, (l1, l2) => l1 == l2).Count(x => x);
var notEqual = list1.Count() - equal;

Zip will skip all remaining elements if one of the lists has no more elements to enumerate (lists have different number of elements):

If the input sequences do not have the same number of elements, the method combines elements until it reaches the end of one of the sequences.

Upvotes: 7

Related Questions