0

I encounter an undefined on associative array values, and cant figure out why!

var list = new Array();

function addNewElement(id, n) {
    var obj = new Object();
    obj["id"] = id;
    obj["n"] = n;
    list.push(obj);
}

function exists(id) {
    for (var o in list) {
        if (o["id"] == id) {
            return true;
        }
    }
    return false;
}

id is string, n is an integer.

In exists o["id"] returns Undefined, for every object in it, but direct after object creation the values are present and accessible via obj["id"].

3 Answers 3

6

That's not how JS for loops work. Your o variable becomes the index, not the value. It should be:

if (list[o]["id"] == id) {

Except really you shouldn't use a for..in on an array, so it should be:

function exists(id) {
    for (var i = 0; i < list.length; i++) {
        if (list[i]["id"] == id) {
            return true;
        }
    }
    return false;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Hm, could you link me to an explanation why JS does not use arrays like almost every other language? (Array[index] is afaik the normal way of accessing arrays?)
Yes, arrayName[index] is what JS does. Where you said Array[index] in your comment, Array would be your list variable and o would be the index, hence list[o] as shown in my answer gets you the object at that array location and list[o]["id"] (or list[o].id) gets you a property of the object at that array location. For reference: MDN's for..in page.
Aw i see, but it is never the less quite non-intuitive behaviour if you come from e.g Java where for(Object o : list) uses an Iterator and returns you the actual object in o, allowing direct access. So javascript for..in is somewhat similar to the iterators in C++ STL.
Yes. There is an array .forEach() method that behaves the way you are expecting where you'd get the actual object in o, but it'd be clunkier to use for your purpose where you want to return out of the containing function as soon as you find a matching value. Also the JS for..in is handy if you need both the key name and the associated value - it's not intended for arrays.
-1

Below is also awesome code snippet : Demo Here

 var list = {};
    setValue("etshte", 393);
    var result = containsKey("etshte");
    alert(result);

    function setValue(key, value) {
        list[key] = value;
    }

    function containsKey(key) {
        if (list[key] == undefined)
            return false;
        else
            return true;
    }

Demo Here

2 Comments

That's not an appropriate use of an array, though it works because arrays are a type of object. In your code list should be a plain object, as in var list = {};. (Note that when I say "it works", it doesn't actually do what the OP was trying as far as creating a list of objects with id and n properties. Also list[key] == undefined is kind of imprecise: what if a property with the specified key has been created but its value is undefined or null? That's not the same as the key not existing at all.)
i used array only because it was used in question
-2

For in loops not only cycle through added members, but also those stored in the prototype

To fix this use:

if (o.hasOwnProperty("id") && o["id"] == id) { /* */ }

4 Comments

Okay didnt know that - makes me wonder why i should use for..in anyway? in that case i just stick to good old for loops instead!
The fact that for-in includes inherited properties really has nothing to do with what's causing the issue. Using o.hasOwnProperty() won't fix anything because o is a string.
Yes right but good to know anyway - he issue remains thats right.the object exists but the contents of o["id"] are undefined, as if i never created the key-value!
On the first iteration of the loop o will be the string "0", the index of the first array element. It will not be the object stored at that index. On the second iteration o will be "1", the second index.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.