简体   繁体   English

Javascript - 将修剪函数应用于数组中的每个字符串

[英]Javascript - Apply trim function to each string in an array

Want to trim each string in an array, eg, given想要修剪数组中的每个字符串,例如,给定

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

output输出

['aa', 'bb']

My first trial is我的第一次尝试是

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

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

Then I tried然后我试过了

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

It works.它有效。 What's the difference?有什么区别?

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

x.map(s => s.trim());

String.prototype.trim.apply is the Function.prototype.apply method without being bound to trim . String.prototype.trim.applyFunction.prototype.apply方法,没有绑定到trim map will invoke it with the string, the index and the array as arguments and nothing ( undefined ) for the this Arg - however, apply expects to be called on functions: map将使用字符串、索引和数组作为参数调用它,而this Arg没有任何内容( undefined ) - 但是, apply期望在函数上调用:

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

What you can do is passing the trim function as the context for call :您可以做的是将trim函数作为call的上下文传递:

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

What happens here is这里发生的是

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

The simple variant without dependencies:没有依赖关系的简单变体:

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

ES6 variant: ES6 变体:

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

ES6 function variant: ES6 函数变体:

const trimmedArray = array => array.map(string => string.trim())

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

$.map([' aa ', ' bb ', '   cc '], $.trim);

First, do it simply :首先,简单地做:

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

Then, the reason why the first one doesn't work is that the string is passed as argument to the callback, not as context.然后,第一个不起作用的原因是字符串作为参数传递给回调,而不是作为上下文。 As you pass no argument to apply , you get the same message you would have got with当您不向apply传递任何参数时,您会得到与使用时相同的消息

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

Now, mostly for fun, let's suppose you're not happy with the fact that map use the callback this way and you'd want to be able to pass a function using the context, not the argument.现在,主要是为了好玩,让我们假设您对map以这种方式使用回调的事实不满意,并且您希望能够使用上下文而不是参数传递函数。

Then you could do this :那么你可以这样做:

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"]

I said "mostly for fun" because modifying objects you don't own (Array's prototype here) is widely seen as a bad practice.我说“主要是为了好玩”,因为修改你不拥有的对象(这里是 Array 的原型)被广泛认为是一种不好的做法。 But you could also make a utilitarian function taking both the array and the callback as arguments.但是您也可以创建一个将数组和回调都作为参数的实用函数。

I just compared some ways to trim an array of strings to get the shortest and fastest method.我只是比较了一些修剪字符串数组的方法,以获得最短和最快的方法。 Who is interested in, here is a performance test on jsperf: http://jsperf.com/trim-array-of-strings谁有兴趣,这里是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);

Note: jQuery is just here to compare the number of characters to type ;)注意: jQuery 只是在这里比较要键入的字符数;)

Keep it simple and stupid:保持简单和愚蠢:

Code代码

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

Output输出

["aa", "b b", "c c"]

Influencing from Bergi's perfect answer, i just would like to add, for those methods which won't take a this argument, you may achieve the same job as follows;受贝尔吉完美答案的影响,我只想补充一点,对于那些不会采用this参数的方法,您可以实现以下相同的工作;

var x = [' aa ', ' bb '],
    y = x.map(Function.prototype.call.bind(String.prototype.trim))
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"]

All major browsers support forEach() , but note that IE supports it only beginning from version 9.所有主流浏览器都支持forEach() ,但请注意IE仅从版本 9 开始支持它。

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

Another ES6 alternative另一个 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']
    ### 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"]     

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM