Question

Looking at the map function in JavaScript, what am I doing wrong here?

// input: [{name: "Kevin"}, {name: "Bob"}];
// output: [{"Kevin" : 0}, {"Bob" : 1}];
var map = function(arr, property) { 

    var i = 0;        
    var m = arr.prototype.map(makeKv);

    // input: {name: "Kevin"}
    // output: {"Kevin" = i} // GLOBAL
    function makeKv(item) {
        return {item: i++};
    };

    console.log("m : " + m);
}

http://jsfiddle.net/FgdSj/2

Also, if you could help please me get rid of the global too.

Was it helpful?

Solution

There are a few issues here:

First,

var m = arr.prototype.map(makeKv);

You don't need prototype here. You only use that when you are using the constructor, like Array.prototype.map. Here, you just need to do arr.map.

Second,

function makeKv(item) {
    return {item: i++};
};

You never declare i anywhere. How can you add one to something that doesn't exist. You need to have var i = 0; before this.

Finally, return {item: i++}; will make a key called literally "item". You need to declare the object first (var ret = {};), then use [item] to set the value.

Array.map's callback is passed the element in the array as the 1st parameter, so item will be an object. You need to do item[property] to get the value you want.

P.S. Don't do "m : " + m in your console.log, that will concat strings, thus converting m to a string. Use , instead: console.log("m : ", m);

So, all together, try:

var map = function(arr, property) { 
    var i = 0;        
    var m = arr.map(makeKv);

    function makeKv(item) {
        var ret = {};
        ret[item[property]] = i++;
        return ret;
    };

    console.log("m : ", m);
}

DEMO: http://jsfiddle.net/FgdSj/3/

EDIT: Array.map's callback is passed the index in the array as the 2nd parameter, so var i = 0; isn't needed here:

var map = function(arr, property) {      
    var m = arr.map(makeKv);

    function makeKv(item, index) {
        var ret = {};
        ret[item[property]] = index;
        return ret;
    };

    console.log("m : ", m);
}

DEMO: http://jsfiddle.net/FgdSj/5/

OTHER TIPS

arr.prototype.map(makeKv);

should be

arr.map(makeKv);

Now you have another issue since it will return

[ { item : 0}, { item : 1} ]

If you change the mapped function to

function makeKv(item) {
    var x = {}
    x[item.name] = i++;        
    return x;
};

it would give you what you want.

JSFiddle

Just call .map directly

arr.map(makeKv)

I, for whatever reason (maybe map is overridden), you want to use the Array.prototype's method

[].map.call(arr, makeKv);

Here's, it's all fixed up for you to match your desired output

// input: [{name: "Kevin"}, {name: "Bob"}], "name"
var map = function(arr, property) { 
    var i = 0; 

    function makeKv(item) {
        var obj = {};
        obj[item[property] = i++;
        return obj;
    };

    return arr.map(makeKv);
}

var result = map([{name: "Kevin"}, {name: "Bob"}], "name");
console.log(result);
// [{"Kevin" : 0}, {"Bob" : 1}];
var map = function(arr, property) { 
    var i = 0; 
    var m = Array.prototype.map(makeKv);

    // input: {name: "Kevin"}
    // output: "Kevin" = i // GLOBAL
    function makeKv(item) {
        return {item: i++};
    };

    console.log("m : " + m);
    return m;
}

map();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top