functional programming - Javascript map native object methods - Stack Overflow

In Python, you can something like this:>>> list(map(str.upper, ['foo','bar'

In Python, you can something like this:

>>> list(map(str.upper, ['foo','bar']))
['FOO', 'BAR']

I would like to be able to do something similar in javascript:

I've tried the following in Chrome using the native map implementation ( ):

['foo','bar'].map(String.prototype.toUpperCase)

['foo','bar'].map(String.prototype.toUpperCase.call)

Why doesn't call work? Is there any elegant way to do this or must I wrap toUpperCase in a callback function? Thx

In Python, you can something like this:

>>> list(map(str.upper, ['foo','bar']))
['FOO', 'BAR']

I would like to be able to do something similar in javascript:

I've tried the following in Chrome using the native map implementation ( https://developer.mozilla/en/JavaScript/Reference/Global_Objects/Array/map ):

['foo','bar'].map(String.prototype.toUpperCase)

['foo','bar'].map(String.prototype.toUpperCase.call)

Why doesn't call work? Is there any elegant way to do this or must I wrap toUpperCase in a callback function? Thx

Share Improve this question asked Nov 12, 2010 at 18:28 BaversjoBaversjo 3,7163 gold badges37 silver badges49 bronze badges 1
  • toUpperCase.call doesn't work because call is resolved against Function.prototype and so is not related to toUpperCase. It looks at this to figure out which method is being called, and the way map invokes the function, this is undefined. – Mike Samuel Commented Nov 12, 2010 at 18:39
Add a ment  | 

5 Answers 5

Reset to default 2

Try:

['foo','bar'].map(Function.prototype.call.bind(String.prototype.toUpperCase))

or for the same effect:

['foo','bar'].map(Function.call.bind("".toUpperCase))

JavaScript's treatment of this is a bad trip.

Modern browsers support this (although it is a recent addition)

var a = ['foo','bar'];
var b = a.map(String.toUpperCase);

alert(b[1]);

or even

var a = ['foo','bar'].map(String.toUpperCase);
alert(a[0]);

example: http://www.jsfiddle/xPsba/

That is because String.prototype.toUpperCase runs on this (Context) object but map function can't set the array element as context. It passes it as an argument. A workaround would be

['foo','bar'].map(function(k) { return String.prototype.toUpperCase.call(k) });

You're all missing the point. :-)

We want to call a method (not a function) on all elements of an array. You can use map:

a.map(function(x){x.frob()})

but that's too much typing. We want to say:

a.mapm(A.frob)

where A is the class of the elements of a and mapm is a new Array method that calls its argument method on each element of this (array a in this case). You could define mapm thus:

Array.prototype.mapm = function (method)
{
    return this.map(function (x) { return method.apply(x) } )
};

and call it thus:

["a", "b", "c"].mapm("".toUpperCase)    ==>     ["A", "B", "C"]

The only problem is that you've added a new element, mapm to every array, though it's ignored by most Array methods, e.g. length and map.

You can use something like this:

function map(arr, fn){
    var i = 0, len = arr.length, ret = [];
    while(i < len){
        ret[i] = fn(arr[i++]);
    }
    return ret;
}

And to use it:

var result = map(['foo', 'bar'], function(item) {
    return item.toUpperCase();
});

console.log ( result ); // => ['FOO', 'BAR']

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745398013a4625969.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信