3

I have an array which has some objects and one of the propery of the object can have dupes viz. Account. Now i want to convert this array to map with key having Account's property value and the corresponding dupes should be stored as an array to that key in the map.

let arr = [];
arr.push({'Key':'1','Record':{'Account':'a','data':'A1'}});
arr.push({'Key':'2','Record':{'Account':'b','data':'123'}});
arr.push({'Key':'3','Record':{'Account':'a','data':'A2'}});
arr.push({'Key':'4','Record':{'Account':'a','data':'A3'}});
arr.push({'Key':'5','Record':{'Account':'c','data':'123'}});
const  accIdMap=  arr.reduce((map,obj) => (map[obj.Record.Account] = obj,map), {});
console.log(arr);
console.log(accIdMap);

So as of now the accIdMap just gets a one to one key-value mapping which is the last one pushed in the array i.e 4 but i want that the output map should have value as an array where ever the keys were duplicated. I tried reduction but that eliminates the duplicate values but i want the duplicate values as an corresponding array.

For example

As is output

{
  "a": {
    "Key": "4",
    "Record": {
      "Account": "a",
      "data": "A3"
    }
  },
  "b": {
    "Key": "2",
    "Record": {
      "Account": "b",
      "data": "123"
    }
  },
  "c": {
    "Key": "5",
    "Record": {
      "Account": "c",
      "data": "123"
    }
  }
}

Desired OutPut (the keys which were duplicated should have the values added as an array)

{
  "a": [{"Key": "4","Record": {"Account": "a","data": "A3"}},{
    "Key": "3",
    "Record": {
      "Account": "a",
      "data": "A2"
    }
  },{
    "Key": "1",
    "Record": {
      "Account": "a",
      "data": "A1"
    }
  }],
  "b": {
    "Key": "2",
    "Record": {
      "Account": "b",
      "data": "123"
    }
  },
  "c": {
    "Key": "5",
    "Record": {
      "Account": "c",
      "data": "123"
    }
  }
}

3 Answers 3

3

You can use reduce like this:

Check if the accumulator already has key with current a.Record.Account. If yes, push the current item in context to it. Else, add a.Record.Account as a key and then push the item to it.

const input = [{'Key':'1','Record':{'Account':'a','data':'A1'}},
{'Key':'2','Record':{'Account':'b','data':'123'}},
{'Key':'3','Record':{'Account':'a','data':'A2'}},
{'Key':'4','Record':{'Account':'a','data':'A3'}},
{'Key':'5','Record':{'Account':'c','data':'123'}}]

const output = input.reduce((acc, a) => 
      ((acc[a.Record.Account] = acc[a.Record.Account] || []).push(a), acc), {})
console.log(output);

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

Comments

1

Doing a check in the reduce function if the value exists already, then based on that you can do the following. If the Account already exists then check if the map has a array on that Account's key. If not create an array with the existing element and the current one by creating an empty array and pushing to that. If it is an array then just push to it. If the Account key doesn't exist then just set the value as the obj.

Update: Reordered the initialization of const m and added comment on code.

let arr = [];
arr.push({'Key':'1','Record':{'Account':'a','data':'A1'}});
arr.push({'Key':'2','Record':{'Account':'b','data':'123'}});
arr.push({'Key':'3','Record':{'Account':'a','data':'A2'}});
arr.push({'Key':'4','Record':{'Account':'a','data':'A3'}});
arr.push({'Key':'5','Record':{'Account':'c','data':'123'}});
const  accIdMap=  arr.reduce((map,obj) => {
    if(map[obj.Record.Account]) { // the property exists and can be an array or the obj
        if(!map[obj.Record.Account].length) { // means just the object. Creating an array then pushing the existing obj to it
            const m = (map[obj.Record.Account]);
            map[obj.Record.Account] = [];
            map[obj.Record.Account].push(m);
        }
        map[obj.Record.Account].push(obj); // if it was an array this will push it to the existing array. If it wasn't the previous if have created and inserted old value and this line pushes to the new array
    } else {
        map[obj.Record.Account] = obj; // just putting the obj value as it wasn't a duplicate
    }
    return map;
}, {});
console.log(arr);
console.log(accIdMap);

Comments

0

This works like what you expected. take this result and match with your desired output.

let arr = [];
arr.push({ 'Key': '1', 'Record': { 'Account': 'a', 'data': 'A1' } });
arr.push({ 'Key': '2', 'Record': { 'Account': 'b', 'data': '123' } });
arr.push({ 'Key': '3', 'Record': { 'Account': 'a', 'data': 'A2' } });
arr.push({ 'Key': '4', 'Record': { 'Account': 'a', 'data': 'A3' } });
arr.push({ 'Key': '5', 'Record': { 'Account': 'c', 'data': '123' } });
var obj = {}
arr.map((e) => {
    var filteredArr = arr.filter((f) => f.Record.Account == e.Record.Account)
    if (filteredArr.length > 1)
        obj[e.Record.Account] = filteredArr
    else if (filteredArr.length != 0)
        obj[e.Record.Account] = filteredArr[0]
})
console.log(JSON.stringify(obj))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.