最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript Convert an array to map keyed with the array property and store the corresponding duplicate key values as array - Sta

programmeradmin1浏览0评论

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);

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"
    }
  }
}
Share Improve this question asked Dec 26, 2018 at 14:02 user1697113user1697113 7002 gold badges14 silver badges25 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 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);

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 ment 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);

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))

发布评论

评论列表(0)

  1. 暂无评论