runnerpaul
runnerpaul

Reputation: 7186

Change structure of a JavaScript object

I have this object structure:

"users": {
        "1": {
            "id": 1,
            "name": "John",
            "email": "[email protected]",
            "supplier_id": 1,
            "supplier_name": [
                "Supplier1"
            ],
            "supplier_code": "SUP001",
            "count": "21"
        }
} 

I'd like to change it so it appears like this:

"users": {
        "1": {
            "id": 1,
            "name": "John",
            "email": "[email protected]",
            "suppliers":[
                {
                    "supplier_id": 1,
                    "supplier_name": [
                        "Supplier1"
                    ]
                }    
            ],
            "supplier_code": "SUP001",
            "count": "21"
        }
}

I tried this hoping it would work:

const group = accumulator[item.id];
  group.suppliers = [];
  group.suppliers = group.suppliers.push(item.supplier_name, item.supplier_id, item.supplier_code);
  return accumulator;

Unfortunately that just seems to give me a count of the objects pushed into suppliers, suppliers isn't an array and supplier_id, supplier_name and supplier_code are still visible outside of suppliers:

"users": {
        "1": {
            "id": 1,
            "name": "John",
            "email": "[email protected]",
            "supplier_id": 1,
            "supplier_name": [
                "Supplier1"
            ],
            "supplier_code": "SUP001",
            "count": "21",
            "suppliers: 3
        }
}

How do I change it to the format I want?

Upvotes: 0

Views: 78

Answers (3)

Mikhail Katrin
Mikhail Katrin

Reputation: 2384

You could use es6 Destructuring assignment, Object.values es2017 (or Object.keys instead). If you assume that users contains more then one user you could use reduce.

In the example below original object won't be mutated.

Hope it helps

const original = {
  "users": {
    "1": {
      "id": 1,
      "name": "John",
      "email": "[email protected]",
      "supplier_id": 1,
      "supplier_name": [
          "Supplier1"
      ],
      "supplier_code": "SUP001",
      "count": "21"
    }
  } 
};

const { users } = original;

const reshaped = Object.values(users).reduce((acc, { id, supplier_id, supplier_name, ...rest }) => {
  acc[id] = {
    ...rest,
    suppliers: [{
      supplier_id,
      supplier_name: [supplier_name]
    }]
  };
  
  return acc;
}, {});

console.log(reshaped);

Upvotes: 2

silicakes
silicakes

Reputation: 6902

Here's a quick and modern solution:

const parseUsers = (users) => {
    let parsedUsers = {};
    for (key in users) {
        const user = users[key];
        // destructuring (or extracting) the relevant keys from the . user object, keeping everything else under 'rest'
        const { supplier_id, supplier_name, ...rest } = user; 
        parsedUsers[key] = {
            ...rest, // spreading back our rest params
            suppliers: [ // creating a new array and populating it with the keys which we previously extracted (along with their corresponding values)
                supplier_id,
                supplier_name
            ]
        }
    }

    return parsedUsers;
}

usage: parseUsers(json.users)

Upvotes: -1

Anurag Srivastava
Anurag Srivastava

Reputation: 14413

You need to use an object to push into the suppliers array. Also, delete the old keys which are not needed.

Edit - You can directly create an array of 1 object. Thanks @Adam

const group = accumulator[item.id];
group.suppliers = [{
    supplier_id: item.supplier_id,
    supplier_name: item.supplier_name,
    supplier_code: item.supplier_code
}];

delete group.supplier_id;
delete group.supplier_name;
delete group.supplier_code;
return accumulator;

Upvotes: 1

Related Questions