Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare two arrays and then return the index of the difference?

I have two arrays that I need to check the difference upon and return the index of that difference.

For example, I currently have two arrays that get updated when the input's value is changed. The newTags array gets updated whenever there is a new tag within the input, such as @testing. I need to compare the newTags array with the oldTags array and return the index of the difference.

I am currently stringifying both arrays and comparing them that way, although it is unable to return the index of the difference.

var newTags = [];
var oldTags = [];

$input.on('keyup', function () {
    var newValue = $input.val();
    var pattern = /@[a-zA-Z]+/ig;
    var valueSearch = newValue.search(pattern);

    if (valueSearch >= 0) {
        newTags = newValue.match(pattern);

        if ((newTags + "") != (oldTags + "")) {
            //Need index of difference here
            console.log(newTags, oldTags);
        }

        oldTags = newTags;
    }
});

Working example

like image 516
Fizzix Avatar asked Mar 18 '15 02:03

Fizzix


2 Answers

You can use a filter to find both the different values and indexes at the same time.

JSFiddle: https://jsfiddle.net/k0uxtnkd/

Array.prototype.diff = function(a) {
    var source = this;
    return this.filter(function(i) {
        if (a.indexOf(i) < 0) {
            diffIndexes.push(source.indexOf(i));
            return true;
        } else {
            return false;
        }
    });
};
var diffIndexes = [];
var newTags = ['a','b','c'];
var oldTags = ['c'];
var diffValues = newTags.diff(oldTags);
console.log(diffIndexes); // [0, 1]
console.log(diffValues); // ['a', 'b']

To convert this to a function instead of add it to the array prototype: JSFiddle: https://jsfiddle.net/k0uxtnkd/1/

function arrayDiff(a, b) {
    return a.filter(function(i) {
        if (b.indexOf(i) < 0) {
            diffIndexes.push(a.indexOf(i));
            return true;
        } else {
            return false;
        }
    });
};
var diffIndexes = [];
var newTags = ['a','b','c'];
var oldTags = ['c'];
var diffValues = arrayDiff(newTags, oldTags);
console.log(diffIndexes); // [0, 1]
console.log(diffValues); // ['a', 'b']
like image 172
Jason W Avatar answered Oct 24 '22 19:10

Jason W


You don't need to loop through both arrays, you can simply loop through both simultaneously:

var findDivergence = function (a1, a2) {
    var result = [], longerLength = a1.length >= a2.length ? a1.length : a2.length;
    for (i = 0; i < longerLength; i++){
        if (a1[i] !== a2[i]) {
            result.push(i);
        }
    }
    return result;
};

console.log(findDivergence(["a","b","c","d","e","f","g","h","i"], ["a","b","d","r","e","q","g"]));
//outputs [2, 3, 5, 7, 8]

This is significantly more efficient than double-looping or using indexOf (both of which will search the second array many more times than necessary). This also handles cases where the same item shows up more than once in a given array, though if one array is longer than the other and the longer one contains an element that is undefined, that index will count as a match.

like image 40
Steve K Avatar answered Oct 24 '22 20:10

Steve K