3

Given the following JSON

{
gif: ['small', 'medium', 'large'],
jpeg: ['tiny', 'huge']
}

I would like to convert each element in the array into a key in a sub object and assign it to it a quantity of 1.

As such

{
gif: {
  small: {quantity: 1},
  medium: {quantity: 1},
  large: {quantity:1}
  },
jpeg: {
  tiny: {quantity:1},
  huge: {quantity: 1}
  }
}

The closest I've come is with the following

for(let image in obj) { 
  obj[image].forEach(size => { obj[image][size] = { quantity:1}})
}

However unfortunately this out puts

{ gif: 
  [ 'small',
    'medium',
    'large',
     small: {quantity: 1},
     medium: {quantity: 1},
     large: {quantity: 1} ],
 jpeg: [ 'huge', 'tiny', tiny: {quantity:1} huge: {quantity: 1 } ] 
} 

Any help would be awesome, thanks

4 Answers 4

4

You can convert it in-place using reduce within forEach loop:

const o = {
  gif: ['small', 'medium', 'large'],
  jpeg: ['tiny', 'huge']
}

Object.keys(o)
  .forEach(
    k => o[k] = o[k].reduce(
      (a, e) => (a[e] = {
        quantity: 1
      }) && a, {}
    )
  )

console.log(o)

And convert into a new object using double reduce:

const o = {
  gif: ['small', 'medium', 'large'],
  jpeg: ['tiny', 'huge']
}

var o2 = Object.keys(o).reduce((n, k) => (n[k] = o[k].reduce((a, e) => (a[e] = {quantity:1}) && a, {})) && n, {})

console.log(o2)

Sign up to request clarification or add additional context in comments.

1 Comment

&& a seems nice. Is it safe? I would have done an Object.assign() instead.
1

You can use the .reduce() method

const obj = {
  gif: ['small', 'medium', 'large'],
  jpeg: ['tiny', 'huge']
};


for (let image in obj) {
  obj[image] = obj[image].reduce((result, item) => {
    result[item] = {
      quantity: 1
    };
    return result;
  }, {});
}

console.log(obj);

2 Comments

While, all the other current solutions also work, and I'm aware the for ...let syntax is the same as Object.keys, this one one looks the simplest and easiest to read in IMHO. Thanks
@Verric in is NOT the same as Object.keys(). in has a very big caveat that you need to be aware of: that is that it includes properties from the prototype chain, which is normally not something you want when iterating over an object's properties.
0

You can use reduce method on Object.keys and inside you can use map and Object.assign to return new object.

const data = {
  gif: ['small', 'medium', 'large'],
  jpeg: ['tiny', 'huge']
}

const result = Object.keys(data).reduce(function(r, e) {
  r[e] = Object.assign({}, ...data[e].map(k => ({[k]: {quantity: 1}})))
  return r;
}, {})
console.log(result)

Comments

0
const obj = {
  gif: ['small', 'medium', 'large'],
  jpeg: ['tiny', 'huge']
}

const objKeys = Object.keys(obj);

for(let i=0;i<objKeys.length;i++){
  const currentKey = objKeys[i];
  obj[currentKey] = obj[currentKey].reduce((sum, element) => { 
    sum[element] = {quantity: 1};
    return sum;
  }, {});
}

This is one solution, you go through the array and replace it with objects

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.