1

I would like to compare 2 "multidimensional" arrays (arrays nested in arrays).

var old_dataArray=new Array(("id-2", "message", "user"), ("id-1", "message", "user"), ("id-0", "message", "user"));
var new_dataArray=new Array(("id-3", "message", "user"), ("id-2", "message", "user"), ("id-1", "message", "user"));

in this case, I would like to get the array("id-3", "message", "user") which is contained only in "old_dataArray" and not in "new_dataArray".

I've tried with the array_diff function presented here. http://phpjs.org/functions/array_diff:309 But it doesn't really work !.

3
  • 3
    You don't have nested arrays there because what you intended to be the inner arrays have parentheses instead of square brackets. Speaking of which, don't bother with the new Array(1,2,3) syntax, just use array literal [1,2,3] syntax. When you say you want to find nested arrays contained only in old_dataArray and not new_dataArray do you mean to compare each nested array by identity or by value? (I.e., compare based on whether they reference the same array object or find them if they have the some number of elements with the same values?) Commented Sep 29, 2011 at 12:10
  • @nnnnnn: I guess you didn't want the upvotes from answering this in the proper place, eh? Commented Sep 29, 2011 at 12:28
  • 1
    @missingno - Oh well, upvotes aren't everything. I didn't post an answer because (as per the second half of my comment) I felt the question was unclear about how to compare the nested arrays. I figured once this was clarified I could post an answer if nobody else had yet, but in the mean time at least I could point out about the square brackets. Commented Sep 29, 2011 at 12:45

2 Answers 2

3

From what I understand, you want to get all arrays in new_dataArray that are not in old_dataArray and I'm assuming that if the first element in each (the 'id-n' element) is the same, then so is the rest of the array. You can do so like this:

// create an array to store our results:
var results = new Array();

// loop through new_dataArray:
outerloop:
for (var i = 0; i < new_dataArray.length; ++i) {

    // loop through old_dataArray to compare the i'th element
    // in new_dataArray with each in old_dataArray:
    for (var j = 0; j < old_dataArray.length; ++j) {

        // check if the ids are the same
        if (new_dataArray[i][0] == old_dataArray[j][0])
            // yes it's there, so move on to the next element of new_dataArray
            continue outerloop;

    }

    // if we get here, continue outerloop; was never called so 
    // this element is not in old_dataArray
    results.push(new_dataArray[i]);

}

// now results contains all arrays that are in new_dataArray 
// but not in old_dataArray

EDIT: If, however, you want ALL the elements in each array to be equal, not just the first (id-n) element, use this:

// create an array to store our results:
var results = new Array();

// loop through new_dataArray:
outerloop:
for (var i = 0; i < new_dataArray.length; ++i) {

    // loop through old_dataArray to compare the i'th element
    // in new_dataArray with each in old_dataArray:
    innerloop:
    for (var j = 0; j < old_dataArray.length; ++j) {

        // check if the arrays are the same size:
        if (new_dataArray[i].length != old_dataArray[j].length)
            // no, so they must be different
            continue innerloop;

        // check if the arrays have the same values
        for (var k = 0; k < old_dataArray[j].length; ++k) {

            if (new_dataArray[i][k] != old_dataArray[j][k])
                // the k'th element is different
                continue innerloop;
        }

        // if we get here, then we have found a match, so move on
        continue outerloop;

    }

    // if we get here, continue outerloop; was never called so 
    // this element is not in old_dataArray
    results.push(new_dataArray[i]);

}

// now results contains all arrays that are in new_dataArray 
// but not in old_dataArray
Sign up to request clarification or add additional context in comments.

2 Comments

+1 for the continue outerloop. (I know some people don't like labels and continues, but then I know some people so stuffy they wouldn't even break out of a non-nested loop; I do like the continue outerloop syntax, especially with meaningful comments like yours.)
Thank you. I always try to minimise use of temporary variables and unnecessary conditional checks. Every clock-cycle counts!
0
var old_dataArray = [["id-2", "message", "user"], ["id-1", "message", "user"], ["id-0", "message", "user"]];
var new_dataArray = [["id-3", "message", "user"], ["id-2", "message", "user"], ["id-1", "message", "user"]];

var result = [];

for (var i = 0; i < new_dataArray.length ; i++) {
    var isInOldArray = false;
    console.log(new_dataArray[i][0]);

    for (var j = 0; j < old_dataArray.length; j++) {
         if (old_dataArray[j][0] === new_dataArray[i][0]) {
             isInOldArray = true;
             break;
         };
    };

    if (!isInOldArray) {
        result.push(new_dataArray[i]);
    };
};

alert(result);

3 Comments

For efficiency, you should break; after setting isInOldArray = true; - there's no point in continuing through the loop after a match has been found.
No problem. In fact, it can be made more efficient still by continueing the outer loop when a match is found and thus removing the need to set, and later check, a boolean. And then we get ... my solution! :-)
This solution works for my small sample array. But for some reason, it doesn't work with a full json object. Maybe I should rephrase. How can I compare 2 json objects deep recursively and return an Array of all changed items ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.