Wonka
Wonka

Reputation: 8674

lodash - How to _.trim an array of objects?

I am trying to use lodash's _.trim to remove leading/trailing whitespace in the key/value like this:

var items = [
             {"key": "  Needs Trim 1  ", "value": "  Needs Trim 2  "},
             {"key": "  Needs Trim 3  ", "value": " Needs Trim 4  "}
            ];

It should look like this after trimming with lodash:

var items = [
             {"key": "Needs Trim 1", "value": "Needs Trim 2"},
             {"key": "Needs Trim 3", "value": "Needs Trim 4"}
            ];

I tried this:

var trimmedItems = _.map(items, _.trim);
console.log(trimmedItems); // outputs ["[object Object]", "[object Object]"]

But I don't think that worked, as the console.log(trimmedItems) doesn't show the actual objects, so I am not sure if they are trimmed. Here is a fiddle showing the issue, console should be open to see the issue as well.

Any idea how to get the fiddle to output the trimmed lodash objects to ensure they are trimmed correctly?

Upvotes: 1

Views: 16670

Answers (5)

aaaaaa
aaaaaa

Reputation: 1386

Mapping is the correct way to go about this, but my solution is more appropriate than meagar's

const items = [
  {
    key1: "  Needs Trim 1  "
    , key2: "  Needs Trim 2  "
  }, {
    key1: "  Needs Trim 3  "
    , key2: " Needs Trim 4  "
  }
];

const result = _.map(items, toTrimmedObject);

console.log(JSON.stringify(result, null, 2));


function toTrimmedObject(obj) {
  return _.mapValues(obj, _.trim);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Upvotes: 2

Alexey
Alexey

Reputation: 2164

Trim + remove white space of all values in object (including nested objects). Skipping non-string values and undefined values.

const trimObject = (obj) => {
  each(obj, (v, k) => {
    if (v !== undefined) {
      if (isObject(v)) {
        obj[k] = trimObject(v)
      } else {
        obj[k] = typeof v === 'string' ? v.trim().replace(/\s+/g, ' ') : v
      }
    }
  })
  return obj
}

Upvotes: 1

Tushar
Tushar

Reputation: 87203

You can use each() as follow.

_.each(items, o => _.each(o, (v, k) => o[k] = v.trim()))

The first each will iterate over items array and the nested each will iterate over the properties in the object in the array. To update he original value in the items array

o[k] = v.trim()

is used. Where o is referencing to the object inside the items array.

For environments where ES6 Arrow function is not supported

_.each(items, function (o) {
    _.each(o, function (v, k) {
        o[k] = v.trim();
    });
});

var items = [{
    "key": "  Needs Trim 1  ",
    "value": "  Needs Trim 2  "
}, {
    "key": "  Needs Trim 3  ",
    "value": " Needs Trim 4  "
}];

_.each(items, o => _.each(o, (v, k) => o[k] = v.trim()))

console.log(items);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-compat/3.10.2/lodash.js"></script>

Using Vanilla JavaScript:

items.forEach(function(o) {
    Object.keys(o).forEach(function(key) {
        o[key] = typeof o[key] === 'string' ? o[key].trim() : o[key];
    });
});

var items = [{
    "key": "  Needs Trim 1  ",
    "value": "  Needs Trim 2  "
}, {
    "key": "  Needs Trim 3  ",
    "value": " Needs Trim 4  "
}];

items.forEach(function (o) {
    Object.keys(o).forEach(function (key) {
        o[key] = typeof o[key] === 'string' ? o[key].trim() : o[key];
    });
});

console.log(items);

Upvotes: 11

user229044
user229044

Reputation: 239301

You need two levels of mapping. One to map the array, and an inner one to map each of the object's properties to a trimmed version of its value:

_.map(items, function (obj) {
  return _.fromPairs(_.map(obj, function (value, key) {
    return [key, _.trim(value)]
  }))
})

Upvotes: 4

TimoStaudinger
TimoStaudinger

Reputation: 42460

You need to trim the key and the value separately.

Applying _.trim() to an object first naively converts the object into a string, resulting in "[object Object]" and then trims this string.


Also, no need to use lodash, as JavaScript already provides all the necessary functionalities natively:

var items = [{
  "key": "  Needs Trim 1  ",
  "value": "  Needs Trim 2  "
}, {
  "key": "  Needs Trim 3  ",
  "value": " Needs Trim 4  "
}];

var out = items.map(function(item) {
  item.key = item.key.trim();
  item.value = item.value.trim();
  return item;
});

console.log(out);

Upvotes: 1

Related Questions