neuront
neuront

Reputation: 9622

Javascript - Apply trim function to each string in an array

Want to trim each string in an array, e.g., 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.

Then I tried

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

It works. What's the difference?

Upvotes: 104

Views: 133644

Answers (12)

nanobar
nanobar

Reputation: 66355

Or this can be solved with arrow functions:

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

Upvotes: 155

Surojit Paul
Surojit Paul

Reputation: 1282

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

console.log(x)

Upvotes: 1

musemind
musemind

Reputation: 1055

The simple variant without dependencies:

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

ES6 variant:

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

ES6 function variant:

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

Upvotes: 41

koteswararao pv
koteswararao pv

Reputation: 89

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

Upvotes: -3

gildniy
gildniy

Reputation: 3913

Another ES6 alternative

const row_arr = ['a ', ' b' , ' c ', 'd'];
const trimed_arr = row_arr.map(str => str.trim());
console.log(trimed_arr); // <== ['a', 'b', 'c', 'd']

Upvotes: -2

Mart&#237;n Silva
Mart&#237;n Silva

Reputation: 47

Keep it simple and stupid:

Code

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

Output

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

Upvotes: 3

Amr
Amr

Reputation: 5159

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.

Upvotes: 1

Redu
Redu

Reputation: 26161

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;

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

Upvotes: 3

Sachin Kainth
Sachin Kainth

Reputation: 46750

If you are using JQuery, then a better way to do this, as it will work with IE8 as well (I need to support IE8) is this:

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

Upvotes: 28

yckart
yckart

Reputation: 33408

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

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 ;)

Upvotes: 5

Bergi
Bergi

Reputation: 664599

String.prototype.trim.apply is the Function.prototype.apply method without being bound to trim. map will invoke it with the string, the index and the array as arguments and nothing (undefined) for the thisArg - however, apply expects to be called on functions:

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:

[' 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

Upvotes: 109

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382160

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

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.

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. But you could also make a utilitarian function taking both the array and the callback as arguments.

Upvotes: 19

Related Questions