1

I have two arrays:

var array_old = [{id:"5436", title:"I Like you boy"}, {id:"5437", title:"Hello how are you"}];
var array_new = [{id:"5436", title:"I Like you boy"}, {id:"1132", title:"I'm fine"}];

$.each(array_old, function(id, array)
{
    if(!$.inArray(array['id'], array_new, 1)>-1){
        alert(array['id'] + " does not exist in array_new");
    }
});

I want to check if the IDs of array_old exist in array_new, so I'm expecting the code to output "5437 does not exist in array_new" in this example.

I can't find any function that would allow me to do that, so how should I do it?

3
  • What's the question??? Are you saying that you're expecting it to alert(), but it's not doing it? Because it sure does: jsfiddle.net/VHb3Q Commented Nov 20, 2012 at 23:50
  • @meetamit it also says that 5436 does not exist, but it does exist, so the script is not working Commented Nov 20, 2012 at 23:56
  • Are you expect the arrays to be in the same order? Would it be OK to sort them? Commented Nov 21, 2012 at 0:01

4 Answers 4

1

http://jsfiddle.net/tppiotrowski/VHb3Q/2/

var array_old = [{
    id: "5436",
    title: "I Like you boy"},
{
    id: "5437",
    title: "Hello how are you"}];
var array_new = [{
    id: "5436",
    title: "I Like you boy"},
{
    id: "1132",
    title: "I'm fine"}];

$.each(array_old, function(old_index, old_obj) {
    var old_id = old_obj['id'];
    var found = false;
    $.each(array_new, function(new_index, new_obj) {
        if (new_obj['id'] == old_id) {
            found = true;
        }
    });
    if (!found) {
        alert(old_id + " does not exist in array_new");
    }
});​
Sign up to request clarification or add additional context in comments.

Comments

1

I found a way myself, but I don't know if this is the best way to do it:

var array_old = [{id: "5436",title: "I Like you boy"},{id: "5437",title: "Hello how are you"},{id: "5438",title: "Hello how are you2"}];
var array_new = [{id: "5436",title: "I Like you boy"},{id: "1132",title: "I'm fine"}];

$.each(array_old, function(id, array){

    found = 0;

    $.each(array_new, function(id2, array2) {

        if(array['id']==array2['id'])
        {
            found++;
        }

    });

    if(found==0)
    {
        alert(array['id']+' does not exist in array_new');
    }

});

http://jsfiddle.net/FAb3k/2/

2 Comments

that solution looks acceptable. you may want to say var found = 0; to keep the variable in the local scope thus preventing it from polluting the global namespace.
you can break the each loop using return false to improve performance also when the value is found
1

Depends on how big your arrays are - you might want to use a more performant solution.

  • The easiest solution (which both you and @Tebb found) has Θ(n*m)
  • If you would optimize this a bit (breaking out if you did [not] found the element - see @gonchuki), you are still at O(n*m)
  • You could assume that both arrays are in the same order, and run only one loop: O(min(n,m)). If you'd need to sort them before that, you'd get O(n*log n+m*log m).
  • Best would be using a hash table for O(1) lookup, resulting in O(n+m). You can easily use a JS object for that:
var counts = {};
for (var i=0; i<array_new.length; i++)
    counts[array_new[i].id] = (counts[array_new[i].id] || 0) + 1;

return array_old.every(function(item) {
    return item.id in counts && counts[item.id]--;
});

(Demo)

4 Comments

could you implement this in a jsfiddle?
jsfiddle.net/t3Ary/3 <<< I'm getting output .. but I don't follow why to place in the given KV pairs in counts?
The most I can come up with is the "return array_old.every" gives us a value whether an item is indexed in counts ... But the current version returns false ... which isn't wildly useful
It doesn't place the KV pairs in counts, but only the keys (ids) which you were looking for. It counts them per id (usually will be resulting in 1), and then requires for each item in the array_old to have a positive count (and decrements it to detect multiple occurrences). It returns false if the arrays do not match, and true otherwise.
0

Throwing in a wild alternative just because it works and it's ultimately easier to read (no idea about performance, but let's skip that since I'm doing it to show another way to do it)

var ids_old = $.map(array_old, function(item) { return item.id; });
var ids_new = $.map(array_new, function(item) { return item.id; });

var duplicates = $.grep(ids_old, function(i, id) { 
    return $.inArray(id, ids_new) !== -1;
});

Be aware that the end result is that you get a list of the duplicate IDs themselves, this other alternative lets you collect the item itself:

var ids_new = $.map(array_new, function(item) { return item.id; });

var duplicates = $.grep(array_old, function(i, item) { 
    return $.inArray(item.id, ids_new) !== -1;
});

Bonus points: even if his example is pure jQuery, notice that on ECMAScript5 compliant browsers you can use the native array counterparts to achieve the same result.

Comments

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.