Croisade
Croisade

Reputation: 219

Combine array of objects into a single object with a nested object

I'm trying to turn this data

[
  {
    key: 'myvar',
    value: 'my value',
    global: false,
  },
  {
    key: 'foo',
    value: 'bar',
    global: false,
  },
  {
    key: 'featureEnabled',
    value: true,
    global: true,
    accountId: 123,

  },
]

into this

{
  myvar: 'my value'
  foo: 'bar'
  123: { 'featureEnabled': true }
}

I was thinking something along the lines of something like below but this will return undefined for objects that don't have an accountId property. I thought there might be a way to use an if statement here.

const globalResponse = Object.assign({}, ...getPreference.map(o => ({ [o.accountId]: { [o.key]: o.value } })))

Upvotes: 2

Views: 71

Answers (2)

Orelsanpls
Orelsanpls

Reputation: 23515

You can use of reduce to build your new object and setup specific triggers for specifics use cases.

function mutateObject(tmpBasis, key, value) {
  tmpBasis[key] = value;
  
  return tmpBasis;
}

const ret = [{
    key: 'myvar',
    value: 'my value',
    global: false,
  },
  {
    key: 'foo',
    value: 'bar',
    global: false,
  },
  {
    key: 'featureEnabled',
    value: true,
    global: true,
    accountId: 123,
  },
  {
    key: 'otherKey',
    value: true,
    global: true,
    accountId: 123,
  },
  {
    key: 'featureEnabled',
    value: true,
    global: true,
    accountId: 512,
  },
].reduce((tmp, {
  key,
  value,
  global,
  accountId,
}) => ({
  ...tmp,

  // If we are in global case, we either create an empty object containing the new key
  // or we add the new key inside of the existing object
  [global ? accountId : key]: global ? mutateObject(tmp[accountId] || {}, key, value) : value,
}), {});

console.log(ret);

Upvotes: 1

Girish Sasidharan
Girish Sasidharan

Reputation: 588

You can use reduce() with a condition inside like below

var myJSON = [{
    key: 'myvar',
    value: 'my value',
    global: false,
  },
  {
    key: 'foo',
    value: 'bar',
    global: false,
  },
  {
    key: 'featureEnabled',
    value: true,
    global: true,
    accountId: 123,

  },
];

let newJSON = myJSON.reduce((target, item) => {
  !!item.accountId ? target[item.accountId] = { [item.key]: item.value } : target[item.key] = item.value;
  return target;
}, {});

console.log(newJSON);

Upvotes: 0

Related Questions