Pass multiple index to function

A

Archos

How to pass a multi-dimensional index to a function? The next code
only works for single index

// ==
function M(index) {
var map = {1: {1: "one"}, 2: {2: "two"}};
console.log(map[index]);
}
// ==
Object { 1="one"}
undefined
undefined

S

Scott Sauyet

How to pass a multi-dimensional index to a function? The next code
only works for single index

function M(index) {
var map = {1: {1: "one"}, 2: {2: "two"}};
console.log(map[index]);}
}
M([1][1]) // undefined

The parameter you pass into your function is undefined. You're trying
to take the second element (index = 1) of a one-element array. You
need to use something like this: `M(1, 1)`. This would do that:

var M = (function() {
var map = {1: {1: "one"}, 2: {2: "two"}};
return function() {
var obj = map;
var i = 0, len = arguments.length;
while (obj && i < len) {
obj = obj[arguments[i++]];
}
return obj;
}
}());

M(1, 1); // one

Note, also that you are using an initial capital letter for your
function, which by strong convention should only be used for a
constructor function.

-- Scott

A

Asen Bozhilov

Scott said:
var M = (function() {
var map = {1: {1: "one"}, 2: {2: "two"}};
return function() {
var obj = map;
var i = 0, len = arguments.length;
while (obj && i < len) {
obj = obj[arguments[i++]];
}
return obj;
}
}());

M(1, 1); // one

Your function makes debugging almost impossible or at least hard.
e.g.

M(1, 2, 3, 4);

IMHO should throwing a TypeError since you have tried to access
property of undefined value, it would definitely improve the
debugging.

for (var i = 0, len = arguments.length; i < len; i++) {
obj = obj[arguments]
}

S

Scott Sauyet

Asen said:
Scott said:
var M = (function() {
var map = {1: {1: "one"}, 2: {2: "two"}};
return function() {
var obj = map;
var i = 0, len = arguments.length;
while (obj && i < len) {
obj = obj[arguments[i++]];
}
return obj;
}
}());
M(1, 1); // one

Your function makes debugging almost impossible or at least hard.
e.g.

M(1, 2, 3, 4);

IMHO should throwing a TypeError since you have tried to access
property of undefined value, it would definitely improve the
debugging.

The decision not to do so was a conscious one. I don't know the OP's
requirements, but I've recently had to implement a significantly more
complicated version of this in which a structured string represented a
path to a node in a complex object. Fetching the value for that path
was not allowed to throw errors; I had to return undefined if any
partial match didn't exist. That obviously colored my suggestion.

That said, I'm not sure I like this:
for (var i = 0, len = arguments.length; i < len; i++) {
obj = obj[arguments]
}

It's not clear to me that this is much more debuggable than my
suggestion:

for (var i = 0, len = arguments.length; i < len; i++) {
obj = obj[arguments]
}

It throws a TypeError, but there's no indication of the actual cause.
I don't know at which level it was undefined. Moreover it would then
handle differently the case where the final node doesn't exist (M(1,
2) returns undefined) and one where an intermediate node doesn't exist
(M(1, 2, 3, 4) throws a TypeError.) Perhaps you find that more
useful. Perhaps the OP would too. I prefer a more uniform behavior.

-- Scott

S

Scott Sauyet

Scott said:
That said, I'm not sure I like this:
for (var i = 0, len = arguments.length; i < len; i++) {
obj = obj[arguments]
}

It's not clear to me that this is much more debuggable than my
suggestion:

for (var i = 0, len = arguments.length; i < len; i++) {
obj = obj[arguments]
}

Sorry, bad edit. There was no reason to show Asen's alternative again
here. Nor actually was there a reason to show mine again, but for the

| var i = 0, len = arguments.length;
| while (obj && i < len) {
| obj = obj[arguments[i++]];
| }

-- Scott