bekliev
bekliev

Reputation: 2651

How to remove spaces of object's keys? [for...in] [keys.forEach] [reduce]

My goal: remove spaces from keys of objects.

For example, I have such records:

const records = [
    { 'Red Blue': true, 'Orange Strawberry': true, 'Abc Xyz': true },
    { 'Blue Red': true, 'Abc Abc': true, 'Abc Xyz': true },
    { 'Yellow Green': true, 'Apple Banana': true, 'Abc Xyz': true },
]

And have to remove spaces of each key of each record, to be like:

[
    { 'RedBlue': true, 'OrangeStrawberry': true, 'AbcXyz': true },
    { 'BlueRed': true, 'AbcAbc': true, 'AbcXyz': true },
    { 'YellowGreen': true, 'AppleBanana': true, 'AbcXyz': true },
]

Questions:

  1. Am I doing right?
  2. Is there another solution that can solve my task?

I wrote 3 solutions: with for in, with Object.keys().forEach and with reduce.

_

Here 3 solutions of mine:

const records = [
  { "Red Blue": true, "Orange Strawberry": true, "Abc Xyz": true },
  { "Blue Red": true, "Abc Abc": true, "Abc Xyz": true },
  { "Yellow Green": true, "Apple Banana": true, "Abc Xyz": true },
];

/* 1) for...in */
console.time && console.time('solution 1');
const solution1 = records.map(record => {
  const newRecord = {};
  for (const key in record) {
    newRecord[key.replace(/\s/g, "")] = record[key];
  }
  return newRecord;
});
console.timeEnd && console.timeEnd('solution 1');

/* 2) Object.keys(records).forEach */
console.time && console.time('solution 2');
const solution2 = records.map(parent => {
  const newParent = {};
  Object.keys(parent).forEach(key => {
    newParent[key.replace(/\s/g, "")] = parent[key];
  });
  return newParent;
});
console.timeEnd && console.timeEnd('solution 2');

/* 3) reduce */
console.time && console.time('solution 3');
const solution3 = records.map(parent => {
  return Object.keys(parent).reduce((acc, key) => ({
    ...acc,
    [key.replace(/\s/g, "")]: parent[key],
  }), {});
});
console.timeEnd && console.timeEnd('solution 3');

/* All solutions has the same result */
console.log({
  solution1,
  solution2,
  solution3,
});
.as-console-wrapper { max-height: 100% !important; top: 0; }

UPDATED: added console.time to measure the execution time of each solution.

Upvotes: 0

Views: 157

Answers (3)

iacobalin
iacobalin

Reputation: 598

You can use some regex to remove spaces:

const records = [
    { 'Red Blue': true, 'Orange Strawberry': true, 'Abc Xyz': true },
    { 'Blue Red': true, 'Abc Abc': true, 'Abc Xyz': true },
    { 'Yellow Green': true, 'Apple Banana': true, 'Abc Xyz': true },
]

const noSpaces = JSON.parse(JSON.stringify(records).replace(/\s(?=\w.+":)/gm, ''))

console.log(noSpaces)

Upvotes: 1

georg
georg

Reputation: 214969

Questions like "what is better" are subjective and the answer is usually "whatever fits you the best as long as it does the trick". However, there's a common consensus that separating code into reusable parts is cleaner in the long run. In your particular example, "modify the keys of some object" and "remove whitespace" are two loosely related parts, which each can be useful on its own, so it's "better" to code them as such, for example:

function mapKeys(obj, fn) {
    let res = {};

    for (let [k, v] of Object.entries(obj))
        res[fn(k)] = v;

    return res;
}

and

let removeSpaces = x => x.replace(/\s+/g, '');

Then, to solve the problem at hand, you just combine both parts together:

newRecords = records.map(rec => mapKeys(rec, removeSpaces))

Upvotes: 2

Francis Leigh
Francis Leigh

Reputation: 1960

const records = [
  { "Red Blue": true, "Orange Strawberry": true, "Abc Xyz": true, hello: 'world' },
  { "Blue Red": true, "Abc Abc": true, "Abc Xyz": true },
  { "Yellow Green": true, "Apple Banana": true, "Abc Xyz": true },
]

console.time && console.time('Execution time');
const newRecords = records.map(r => {
  const rKeys = Object.keys(r)
  let refObj = {}
  
  rKeys.forEach(k => {
    let tempKey = k
    
    if (k.indexOf(' ') !== -1) tempKey = k.replace(' ', '')
    
    refObj[tempKey] = r[k]
  })
  
  return refObj
});
console.timeEnd && console.timeEnd('Execution time');

console.log(newRecords)

Upvotes: 1

Related Questions