91

想要修剪数组中的每个字符串,例如,给定

x = [' aa ', ' bb '];

输出

['aa', 'bb']

我的第一次试验是

x.map(String.prototype.trim.apply)

它在铬中得到“TypeError: Function.prototype.apply was called on undefined, which is an undefined and not a function”。

然后我尝试了

x.map(function(s) { return String.prototype.trim.apply(s); });

有用。有什么不同?

4

12 回答 12

130

或者这可以用箭头函数来解决:

x.map(s => s.trim());
于 2016-12-16T11:41:58.060 回答
105

String.prototype.trim.apply是不受约束的Function.prototype.apply方法trimmap将使用字符串、索引和数组作为参数调用它,而Argundefined没有任何 ( ) - 但是,期望在函数上调用它:thisapply

var apply = String.prototype.trim.apply;
apply.call(undefined, x[0], 0, x) // TypeError

您可以做的是将trim函数作为上下文传递call

[' aa ', ' bb '].map(Function.prototype.call, String.prototype.trim)
// ['aa', 'bb']

这里发生的是

var call = Function.prototype.call,
    trim = String.prototype.trim;
call.call(trim, x[0], 0, x) ≡
      trim.call(x[0], 0, x) ≡
            x[0].trim(0, x); // the arguments don't matter to trim
于 2013-10-10T11:25:11.100 回答
32

没有依赖关系的简单变体:

 for (var i = 0; i < array.length; i++) {
     array[i] = array[i].trim()
 }

ES6 变体:

const newArray = oldArray.map(string => string.trim())

ES6 函数变体:

const trimmedArray = array => array.map(string => string.trim())
于 2015-10-14T10:09:18.963 回答
28

如果您使用的是 JQuery,那么更好的方法是这样做,因为它也适用于 IE8(我需要支持 IE8)是这样的:

$.map([' aa ', ' bb ', '   cc '], $.trim);
于 2014-05-14T08:58:46.797 回答
16

首先,简单地做:

x.map(function(s) { return s.trim() });

然后,第一个不起作用的原因是字符串作为参数传递给回调,而不是作为上下文。当您不向 传递任何参数时apply,您会收到与您相同的消息

var f = String.prototype.trim.apply; f.call();

现在,主要是为了好玩,让我们假设您对以这种方式使用回调的事实不满意,map并且您希望能够使用上下文而不是参数来传递函数。

然后你可以这样做:

Object.defineProperty(Array.prototype, "maprec", {
  value: function(cb){
      return this.map(function(v){ return cb.call(v) })
  }
});
console.log([' aa ', ' bb '].maprec(String.prototype.trim)); // logs ["aa", "bb"]

我说“主要是为了好玩”,因为修改你不拥有的对象(这里是 Array 的原型)被广泛认为是一种不好的做法。但是您也可以创建一个实用函数,同时将数组和回调作为参数。

于 2013-10-10T11:03:07.923 回答
5

我只是比较了一些修剪字符串数组的方法,以获得最短和最快的方法。谁有兴趣,这里是对jsperf的性能测试:http: //jsperf.com/trim-array-of-strings

var chunks = "  .root  ,  .parent  >  .child  ".split(',')
var trimmed1 = chunks.map(Function.prototype.call, String.prototype.trim);
var trimmed2 = chunks.map(function (str) { return str.trim(); });
var trimmed3 = chunks.map(str => str.trim());
var trimmed4 = $.map(chunks, $.trim);

注意:jQuery 只是在这里比较要输入的字符数;)

于 2015-11-08T14:20:30.137 回答
4

保持简单和愚蠢:

代码

[' aa ', ' b b ', '   c c '].map(i=>i.trim());

输出

["aa", "b b", "c c"]
于 2017-11-06T16:38:16.480 回答
3

受Bergi完美答案的影响,我只想补充一下,对于那些不会this争论的方法,您可以完成以下相同的工作;

var x = [' aa ', ' bb '],
    y = x.map(Function.prototype.call.bind(String.prototype.trim))
于 2016-09-19T20:53:42.280 回答
1
var x = [" aa ", " bb "];
console.log(x); // => [" aa ", " bb "]

// remove whitespaces from both sides of each value in the array
x.forEach(function(value, index){
  x[index] = value.trim();
});

console.log(x); // => ["aa", "bb"]

所有主流浏览器都支持forEach(),但请注意IE仅从版本 9 开始支持。

于 2016-09-25T10:12:28.730 回答
1

x = [' aa ', ' bb ', 'cccc '].toString().replace(/\s*\,\s*/g, ",").trim().split(",");

console.log(x)

于 2021-08-12T13:11:28.340 回答
-1
    ### Code
    <!-- language: lang-js -->

     var x=  [' aa ', ' b b ', '   c c ']
var x = x.split(",");
            x = x.map(function (el) {
                return el.trim();
                console.log(x)

    ### Output
    <!-- language: lang-none -->
        ["aa", "b b", "c c"]     
于 2019-02-15T09:29:58.837 回答
-2

另一个 ES6 替代方案

const row_arr = ['a ', ' b' , ' c ', 'd'];
const trimed_arr = row_arr.map(str => str.trim());
console.log(trimed_arr); // <== ['a', 'b', 'c', 'd']
于 2018-01-08T11:34:13.547 回答