0

I would like to transform the follow array into a slightly modified object (see below). I'm also trying to practice using the spread operator, but haven't been able to figure out how to do it. I'm trying to avoid using lodash (for educational purposes).

Starting array:

var arr = [
    { mainkey: 'John', val1: 'ABC', val2: '..', val3: '..' },
    { mainkey: 'Mary', val1: 'DEF', val2: '..', val3: '..' },
    { mainkey: 'Ann', val1: 'XYZ', val2: '..', val3: '..' }
  ];

to final object:

newObj = {
  John: {val1: 'ABC', val2: '..', val3: '..' },
  Mary: {val1: 'DEF', val2: '..', val3: '..' },
  Ann:  {val1: 'XYZ', val2: '..', val3: '..' }
}

Without using the spread operator, this gets close, but not where I need to be:

var result = arr.reduce(function(map, obj) {
    map[obj.mainkey] = obj.val1;
    // map[obj.mainkey] = { obj.val1, obj.val2 }; <-- DOESNT WORK
    return map;
}, {});

With the spread operator anything I do fails.

Other posts with helpful content:

2 Answers 2

2

Short answer

const newObj = arr.reduce(
    (acc, { mainkey, ...rest }) => ({ ...acc, [mainkey]: rest }),
    {}
  )

Explained

We're calling Array.prototype.reduce(), and for each object within the array, deconstructing mainkey from the rest of the properties (so mainkey could be John andrest could be something like this: {val1: 'ABC', val2: '..', val3: '..' }.

Then, we want to return the accumulator with a deep change, so we use the spread operator, followed by setting the the interploated mainkey property ([mainkey]) to be rest.

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

1 Comment

Thank you for the explanation with it @guy, that helps a lot (especially since I was trying this for educational purposes, even though it's needed for my app as well)
1

simply change to..

    var result = arr.reduce(function(map, obj) {
        map[obj.mainkey] = {
            val1: obj.val1,
            val2: obj.val2,
        };
        return map;
    }, {});        

UPDATE: add other dynamic version.

var result = arr.reduce(function(map, obj) {
    let targetProps = Object.getOwnPropertyNames(obj).filter(
        (prop) => prop !== "mainkey"
    );
    map[obj.mainkey] = {};
    targetProps.forEach( (prop) => {
        map[obj.mainkey][prop] = obj[prop];
    });
    return map;
}, {});   

4 Comments

Thank you @panghea for showing how to adapt my original!
If you're interested in helping me complete this version of it: how would you deal with having 10+ values without having to spell them all out (or a dynamic amount?)
add a dynamic version :)
You're so awesome!

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.