19

Is there a way to trim all properties of an object? In other words, can I change that:

{a: ' a', b: 'b ', c: ' c '}

To this:

{a: 'a', b: 'b', c: 'c'}

It seems I can't map an object, so how can I apply a function to all properties an get the object back?

rap-2-h
  • 30,204
  • 37
  • 167
  • 263
  • 2
    While that doesn't answer the exact, narrow, question posed; I would say that it should be very easy to get to a solution following the answer posted there. – zero298 Jul 31 '18 at 14:48
  • dose it need to be deep also? – Endless Jul 31 '18 at 14:48
  • think this might be the closest thing to map an deep object `JSON.stringify(obj, (k, v) => typeof v === 'string' ? v.trim() : v)` – Endless Jul 31 '18 at 15:04

5 Answers5

28

You can use Object.keys() method to iterate the object properties and update its values:

Object.keys(obj).forEach(k => obj[k] = obj[k].trim());

Demo:

var obj = {
  a: ' a',
  b: 'b ',
  c: ' c '
};

Object.keys(obj).forEach(k => obj[k] = obj[k].trim());
console.log(obj);

Edit:

If your object values can be of other data types(not only strings), you can add a check to avoid calling .trim() on non strings.

Object.keys(obj).forEach(k => obj[k] = typeof obj[k] == 'string' ? obj[k].trim() : obj[k]); 

var obj = {
  a: ' a',
  b: 'b ',
  c: ' c ',
  d: 500
};

Object.keys(obj).forEach(k => obj[k] = typeof obj[k] == 'string' ? obj[k].trim() : obj[k]);

console.log(obj);
nabeelfarid
  • 4,156
  • 5
  • 42
  • 60
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
  • 7
    `forEach` would be preferable over `map`. – pymarco Mar 25 '19 at 23:02
  • 2
    @photo Why would it be? `.map` is designed for such things. – cнŝdk Mar 26 '19 at 09:20
  • 3
    Because `map` is used to return a new transformed array. Here we're just need to loop through and modify the `obj`. – pymarco Mar 26 '19 at 16:54
  • This don't work if object contains object attributes – maroodb Aug 27 '19 at 09:20
  • @maroodb this portion of code were dedicated for the OP code, which contains only `string` values, in the first place, but we can change it to avoid such thing. I made an edit. – cнŝdk Aug 27 '19 at 09:25
  • 1
    @pymarco I observe that .map is faster than .forEach, make me correct if I am wrong. – Jigar Prajapati Apr 10 '20 at 08:03
  • @pymarco No you are not wrong, [`.map()` is a little bit faster than `.foreach`](https://medium.com/@JeffLombardJr/understanding-foreach-map-filter-and-find-in-javascript-f91da93b9f2c#221d), but `for`loops are always faster :) – cнŝdk Apr 10 '20 at 08:32
  • I would suggest using forEach instead of map, because its purpose not to return an array, but to change object properties. By doing that you would avoid "Code Smells" – D0mm Nov 20 '21 at 18:13
  • @D0mm Fair enough, I edited my answer to use `.forEach()` as it was recommended and as we will just edit the original `array`. – cнŝdk Nov 20 '21 at 23:01
7

You can use Object.keys to reduce and trim the values, it'd look something like this:

function trimObjValues(obj) {
  return Object.keys(obj).reduce((acc, curr) => {
    acc[curr] = obj[curr].trim()
    return acc;
  }, {});
}


const ex = {a: ' a', b: ' b', c: ' c'};
console.log(trimObjValues(ex));
Alexandre Wiechers Vaz
  • 1,587
  • 2
  • 18
  • 21
3

You can do that by looping through it.

for(var key in myObject) {
    myObject[key] = myObject[key].trim();
}
Sookie Singh
  • 1,543
  • 11
  • 17
  • I think you need to watch out for this because `for...in` will go up the prototype chain and iterate over all those properties too – Ollie Khakwani Oct 23 '19 at 15:52
  • This can fail with on non-string objects without a trim function. Add a sanity check `if (typeof parsed_pg_request[key] == 'string') {}` – Stevoisiak Mar 10 '23 at 23:08
1

You can use a use reduce to create an object with the values you're looking for:

const test = {a: ' a', b: 'b ', c: ' c '}
const trimAllValues = input => Object.keys(input)
  .reduce((prev, next) =>
    Object.assign(prev, {
      [next]: test[next].replace(/\s+/g, '')
    }), {});
  
const result = trimAllValues(test)
console.log(result)

Lodash's mapValues will be more performant and have better browser support. You can either use lodash, or alternatively have a look at their source and implement the same:

function mapValue(object, iteratee) {
  object = Object(object)
  const result = {}

  Object.keys(object).forEach((key) => {
    result[key] = iteratee(object[key], key, object)
  })
  return result
}
OliverRadini
  • 6,238
  • 1
  • 21
  • 46
0
const object1 = {
  a: ' somestring',
  b: ' a',
  c: 'a '
};

const newVals = Object.values(object1).map(val => val.trim());
console.log(newVals); //["somestring", "a", "a"]
Srinivas
  • 1,516
  • 3
  • 17
  • 27