I have an array of arbitrary values. I Wrote a function that transforms the array to an array of functions that return the original values, so instead of calling a[3], I will call a3.

Here is my code which does not work? code. It gives this error Cannot call method '1' of undefined.

var numToFun = [1, 2, { foo: "bar" }];
var numToFunLength = numToFun.length;

function transform(numTo) {
    for (var i = 0; i < numToFunLength; i++) {
        (function(num){
            numTo.unshift(function() {
                return num;
            });
        }(numTo.pop())) 
    }
}

var b = transform(numToFun);

console.log(numToFun);
console.log(b[1]());​
share|improve this question

72% accept rate
feedback

3 Answers

up vote 2 down vote accepted

Others have already answered your question while I was writing mine but I will post it anyway - this may be somewhat easier to follow without all of those popping and unshifting:

function transform(numTo) {
    var r = [];
    for (var i = 0; i < numTo.length; i++) {
        r[i] = (function (v) {
            return function() {
                return v;
            }
        }(numTo[i]));
    }
    return r;
}

(I have also changed the hard-coded length from numToFunLength to numTo.length so the transform() function would work for other inputs than only the global numToFun variable.)

See DEMO.

UPDATE: even more elegant way to do it using the Sugar library:

function transform(array) {
    return array.map(function (v) {
        return function() {
            return v;
        }
    });
}

I like this syntax because it makes it more explicit that you want to map an array of values to an array of functions that return those values.

See DEMO.

share|improve this answer
+1 from me, certainly simpler and cleaner. And even the original array is preserved! – bažmegakapa Jul 24 at 9:19
Is it efficient way to do this? I mean is it faster tan mine solution? – x4f4r Jul 24 at 9:22
1  
@al0ne evenings: well, it is certainly faster to read if you ask me. ;) Other than that I can't imagine any use case where the difference in speed of both of those solutions would be even noticeable. I would always recommend starting from the most readable way to write your code and only consider optimising it for speed when you profile it and when it really matters. Now when I'm thinking about it there may be even more elegant solution which I may post in few minutes. – rsp Jul 24 at 9:36
feedback

Your function transform does not return anything. That is why b is undefined.

return numTo;

jsFiddle Demo

On the other hand, the array will be passed to the function as a reference anyways, so the original array will be changed. It is not a problem if you don't return anything, just omit the var b = transform(numToFun); line and simply write transform(numToFun).

share|improve this answer
Thanks it is working now. Could you tell me is this a good way to achieve what I am trying to achieve? – x4f4r Jul 24 at 9:11
@al0neevenings Well, seems like it works. A tricky way for sure :). – bažmegakapa Jul 24 at 9:14
feedback

Your transform function isn't returning anything. So b is undefined

share|improve this answer
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.