Remi
Remi

Reputation: 5367

Change objects properties in an immutable way for specific keys

If the value for pre-defined keys are an empty string, then I'd like to change that to a null value instead.

So:

const foo = {
  first: '',
  second: 'bar',
  third: '',
  fourth: '',
  fifth: '',
}

Should be normalised to:

const foo = {
  first: null,
  second: 'bar',
  third: '',
  fourth: null,
  fifth: '',
}

Now the following example works:

const normalize = (payload, keys) => {
  const clone = { ...payload }
  Object.entries(payload).forEach(([key, value]) => {
    if (keys.includes(key) && value === '') {
      clone[key] = null;
    }
  });
  return clone;
}

const foo = {
  first: '',
  second: 'bar',
  third: '',
  fourth: '',
  fifth: '',
}

console.log(normalize(foo, ['first', 'third']));

But the 'clone' variable is not that savvy.

Now there is a commonly used method by using Object.assign().

Is it possible to do this?

Upvotes: 0

Views: 548

Answers (4)

Abhilash
Abhilash

Reputation: 2256

How about this?

Refer to your keys in norm, return new mapping as null if it's to be normalized otherwise the empty string itself.

const foo = {
  first: '',
  second: 'bar',
  third: '',
  fourth: '',
  fifth: '',
}, norm = ['third', 'fifth'];

const normalize = (payload, keys) => {
    return keys.reduce((a, k) => a[k] === "" && (a[k] = null) || a, {...payload})
}

Output:

const norm = ['third', 'fifth'];
normalize(foo, norm)

{first: "", second: "bar", third: null, fourth: "", fifth: null}

Upvotes: 0

zb22
zb22

Reputation: 3231

You can use iterate with for...in and check if the key match with some()

const foo = {
  first: '',
  second: 'bar',
  third: '',
  fourth: '',
  fifth: '',
}

const normalize = ({...obj}, arr) => {
  for (let key in obj) {
    if(arr.some(k => k === key)) {
      obj[key] = null;
    }
  }

  return obj;
}

console.log(normalize(foo, ['third', 'fifth']));

Upvotes: 0

EugenSunic
EugenSunic

Reputation: 13703

Why not loop through the array and mutate the object

const foo = {
  first: '',
  second: 'bar',
  third: '',
  fourth: '',
  fifth: '',
}


function normalize(obj, arr) {
const newObj={...obj}
  for (let i = 0; i < arr.length; i++) {
    newObj[arr[i]] = null;
  }
  return newObj;
}
console.log(normalize(foo, ['first', 'third']));

Upvotes: 0

charlietfl
charlietfl

Reputation: 171669

Alternate approach looping over the keys argument array. No point in looping over all the keys in the object rather just the required ones

const normalize = (payload, keys) => {
  return keys.reduce((a, k) => {
    (a[k] === '') && (a[k] = null)
    return a;
  }, { ...payload })
}

const foo = {
  first: '',
  second: 'bar',
  third: '',
  fourth: '',
  fifth: '',
}

console.log(normalize(foo, ['first', 'third']));

Upvotes: 3

Related Questions