Подтвердить что ты не робот

Javascript - применить функцию trim к каждой строке в массиве

Хотите обрезать каждую строку в массиве, например, заданную

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

Выход

['aa', 'bb']

Моя первая пробная версия

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

Он получил "TypeError: Function.prototype.apply был вызван на undefined, который является undefined, а не функцией" в хроме.

Затем я попробовал

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

Это работает. Какая разница?

4b9b3361

Ответ 1

String.prototype.trim.apply - это Function.prototype.apply метод без привязки к trim. map будет вызывать его со строкой, индексом и массивом в качестве аргументов и ничего (undefined) для this Arg - однако apply ожидает вызова функций:

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

Ответ 2

Или это можно решить с помощью функций стрелок:

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

Ответ 3

Если вы используете JQuery, то лучший способ сделать это, так как он будет работать и с IE8 (мне нужно поддерживать IE8):

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

Ответ 4

Сначала сделайте это просто:

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 здесь) широко рассматривается как плохая практика. Но вы также можете использовать утилитарную функцию, которая принимает как массив, так и обратный вызов в качестве аргументов.

Ответ 5

Простой вариант без зависимостей:

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

Вариант ES6:

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

Вариант функции ES6:

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

Ответ 6

Я просто сравнил некоторые способы обрезки массива строк, чтобы получить самый короткий и быстрый метод. Кто интересуется, вот тест производительности на 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 только для сравнения количества символов для ввода;)

Ответ 7

Воздействуя на идеальный ответ Берги, я просто хотел бы добавить, что для тех методов, которые не принимают аргумент this, вы можете достичь той же работы, что и ниже:

var x = [' aa ', ' bb '],
    y = x.map(Function.prototype.call.bind(String.prototype.trim))

Ответ 8

Держите его простым и глупым:

Код

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

Выход

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

Ответ 9

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.

Ответ 10

Другая альтернатива ES6

let row_arr = ['a ', ' b' , ' c ', 'd'];
let trimed_arr = array_map('trim', row_arr);
console.log(trimed_arr); // <== ['a', 'b', 'c', 'd']