简体   繁体   中英

AngularJS combining objects in array on properties

I have a large array of objects (1500+) and the objects match on one of the properties. So the overall number of objects could be reduced eg for better performance in ng-repeat. I'm kind of new to AngularJS and JS itself, so help is much appreciated!

my Array of Objects (simplified)

myArray = [
    {
        "role": "user111",
        "operation": "create",
        "concept": "folder"
    },
    {
        "role": "user111",
        "operation": "create",
        "concept": "task"
    },
    {
        "role": "user111",
        "operation": "delete",
        "concept": "task"
    },
    {
        "role": "user222",
        "operation": "create",
        "concept": "folder"
    },
    {
        "role": "user222",
        "operation": "create",
        "concept": "task"
    },
    {
        "role": "user222",
        "operation": "delete",
        "concept": "task"
    }
]

desired Output

dreamArray = [
    {
        "role": "user111",
        "operation": {
               "create": ["folder", "task"],
               "delete": ["task"]
                      }
    },
    {
        "role": "user222",
        "operation": {
                   "create": ["folder", "task"],
                   "delete": ["task"]
                      }
    }
]

You could use a hash table and store the reference to the groups.

 var array = [{ role: "user111", operation: "create", concept: "folder" }, { role: "user111", operation: "create", concept: "task" }, { role: "user111", operation: "delete", concept: "task" }, { role: "user222", operation: "create", concept: "folder" }, { role: "user222", operation: "create", concept: "task" }, { role: "user222", operation: "delete", concept: "task" }], grouped = array.reduce(function (hash) { return function (r, o) { if (!hash[o.role]) { hash[o.role] = {}; r.push({ role: o.role, operation: hash[o.role]}); } hash[o.role][o.operation] = hash[o.role][o.operation] || []; hash[o.role][o.operation].push(o.concept); return r; }; }(Object.create(null)), []); console.log(grouped); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

You can do this using forEach() loop and thisArg parameter.

 var myArray = [{"role":"user111","operation":"create","concept":"folder"},{"role":"user111","operation":"create","concept":"task"},{"role":"user111","operation":"delete","concept":"task"},{"role":"user222","operation":"create","concept":"folder"},{"role":"user222","operation":"create","concept":"task"},{"role":"user222","operation":"delete","concept":"task"}] var result = []; myArray.forEach(function(e) { if(!this[e.role]) { this[e.role] = {role: e.role, operation: {[e.operation]: [e.concept]}} result.push(this[e.role]); } else { var op = this[e.role].operation[e.operation] if(op) op.push(e.concept) else this[e.role].operation[e.operation] = [e.concept] } }, Object.create(null)) console.log(result) 

Using reduce() and find()

var myArray = [{ role: "user111", operation: "create", concept: "folder" }, { role: "user111", operation: "create", concept: "task" }, { role: "user111", operation: "delete", concept: "task" }, { role: "user222", operation: "create", concept: "folder" }, { role: "user222", operation: "create", concept: "task" }, { role: "user222", operation: "delete", concept: "task" }],

const dreamArray = myArray.reduce((acc, item) => {
    let obj = acc.find(e => e.role === item.role);
  if(!obj){
    obj = {"role" : item.role, "operation": {[item.operation]: [item.concept]}};
    acc.push(obj);
  }else{
    obj.operation[item.operation] = obj.operation[item.operation] || [];
    obj.operation[item.operation].push(item.concept);
  }
  return acc;
}, []);

console.log(dreamArray);

As I have mentioned in my comment, if you happen to receive the data already sorted on the role property (which you say so) then the required operation boils down to a very simple .reduce() operation and can be implemented with O(n) time complexity as follows;

 var data = [{"role":"user111","operation":"create","concept":"folder"},{"role":"user111","operation":"create","concept":"task"},{"role":"user111","operation":"delete","concept":"task"},{"role":"user222","operation":"create","concept":"folder"},{"role":"user222","operation":"create","concept":"task"},{"role":"user222","operation":"delete","concept":"task"}], result = data.reduce((r,c,i) => !i || r[r.length-1].role !== c.role ? r.concat({"role": c.role, "operation": c.operation === "create" ? {"create": [c.concept], "delete": []} : {"create": [], "delete": [c.concept]}}) : r[r.length-1].operation[c.operation].includes(e => e === c.concept) ? r :(r[r.length-1].operation[c.operation].push(c.concept),r), []); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM