Velocity Reviews > Pass multiple index to function

# Pass multiple index to function

Archos
Guest
Posts: n/a

 02-07-2012
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])

Object { 1="one"}

>> M([1][1])

undefined
undefined

Scott Sauyet
Guest
Posts: n/a

 02-07-2012
On Feb 7, 8:53*am, Archos <(E-Mail Removed)> wrote:
> 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

Asen Bozhilov
Guest
Posts: n/a

 02-07-2012
Scott Sauyet wrote:

> * 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[i]]
}

Scott Sauyet
Guest
Posts: n/a

 02-08-2012
Asen Bozhilov wrote:
> Scott Sauyet wrote:
>> * 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[i]]
> * }

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[i]]
* }

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

Scott Sauyet
Guest
Posts: n/a

 02-08-2012
Scott Sauyet wrote:
> That said, I'm not sure I like this:
>
>> * for (var i = 0, len = arguments.length; i < len; i++) {
>> * * obj = obj[arguments[i]]
>> * }

>
> 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[i]]
> ** *}

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