bobber205
bobber205

Reputation: 13372

Searching for element in an array -- *Not* original object specific

http://jsfiddle.net/jENDR/3/

Something like this

var test = {a: 'a', b: 'b'}; var test2  =  {a: 'a', b: 'b'};

var a = [];

a.push(test);

alert($.inArray(test2, a));

Test2 = -1

Test = 0

Why is this? The objects should be identical right? What kind of comparison is it doing?

EDIT:

Clarifying some things. All the answers below are extremely informative. I am using an array to store a runtime pair of values a "page" and a "directory". These are normally separated unrelated values. I wanted to setup a array of certain pair values and be able to get those two unrelated, form that key pair relationship by creating an object, then searching an array of "allowed" pairs using this method.

I'll use the custom search function for this. Thanks SO!

Upvotes: 0

Views: 426

Answers (4)

brandizzi
brandizzi

Reputation: 27060

When you write {a: 'a', b: 'b'}, you are creating a new object in JavaScript. When you write it again, you create another object, although both objects contains the same values. When you attribute it to variables, the variables just contains references ("pointers") for each object. When you write

var test = {a: 'a', b: 'b'}; 
var test2 = {a: 'a', b: 'b'};

You got two variables pointing to two objects:

References

When you compare the two variables, you just compare the pointers. Since the two objects are different, the pointers are different and the result of the comparison is false. OTOH, if you have done the code below

var test = {a: 'a', b: 'b'}; 
var test2 = test;

the result is that test and test2 point to the same object and are equal.

enter image description here

(More about references on Wikipedia. It would be good to read about pointers too).

What you want to do use a deep comparison in the $.inArray() function. If your objective would be to just compare values, I would recommend you to use the Underscore.js isEqual() function. Since it is not the case, and $.inArray() does not accept a comparator as parameter, I bet you will have to implement it manually:

function inArray(element, array) {
    for (var key in array) {
        if (_.isEqual(element, array[key])) {
            return true;
        }
    }
    return false;
}

EDIT: well, it would be awesome if our function does receive the comparator as a parameter!

function inArray(element, array, cmp) {
    if (typeof cmp != "function") {
        cmp = function (o1, o2) {
            return o1 == o2;
        };
    }
    for (var key in array) {
        if (cmp(element, array[key])) {
            return true;
        }
    }
    return false;
}

Testing in Node.js:

> inArray(test2, a)
false
> inArray(test2, a, function(o1, o2){return o1 === o2;})
false
> inArray(test2, a, _.isEqual)
true

Of course, this brings more complexity for your specific problem, so you do not need to use it. However, I think it may be valid to register the idea :)

Upvotes: 1

Petar Ivanov
Petar Ivanov

Reputation: 93040

There are two different objects (even though containing the same values).

test == test2

evaluates to false.

Check How do you determine equality for two JavaScript objects?

Upvotes: 0

Joe
Joe

Reputation: 82624

You can compare each element:

function compareObjects(a, b) {
    var areEqual = true;
    for (var key in a) {
        if (b[key] !== a[key]) {
            areEqual = false;
            break;
        }
    }
    for (var key in b) {
        if (b[key] !== a[key]) {
            areEqual = false;
            break;
        }
    }
    return areEqual;
}

Or maybe serialize the records and string compare:

JSON.stringify({a: 1, b: 2}) === JSON.stringify({"a": 1, "b": 2}); // true

Upvotes: 1

jfriend00
jfriend00

Reputation: 707546

a is an array who's first element is the test object.

inArray tests to see if any array element in the passed in array is the same as the test value. So, you're looking in the a array for the test2 object. But, the test2 object is not in that array. test2 may have the same contents as test, but it isn't the same object.

In summary, your issue is that:

test != test2

because they are not the same object. Their contents may be the same, but they are not the same object.

If you want to compare two objects for the same contents, see this previous post: Object comparison in JavaScript.

Upvotes: 0

Related Questions