Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 e.g. 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"]
                      }
    }
]
like image 604
DTR9000 Avatar asked Jul 10 '26 06:07

DTR9000


2 Answers

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)
like image 98
Nenad Vracar Avatar answered Jul 11 '26 18:07

Nenad Vracar


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; }
like image 37
Nina Scholz Avatar answered Jul 11 '26 18:07

Nina Scholz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!