AngularJS在属性上组合数组中的对象

时间:2017-06-07 14:14:06

标签: javascript angularjs arrays object underscore.js

我有一大堆对象(1500+),并且其中一个属性的对象匹配。因此可以减少对象的总数,例如在ng-repeat中获得更好的性能。 我是AngularJS和JS本身的新手,所以非常感谢帮助!

我的对象数组(简化)

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"
    }
]

所需的输出

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

4 个答案:

答案 0 :(得分:3)

您可以使用哈希表并将引用存储到组中。

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

答案 1 :(得分:3)

您可以使用forEach()循环和thisArg参数执行此操作。



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)




答案 2 :(得分:1)

使用reduce()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);

答案 3 :(得分:0)

正如我在评论中提到的,如果您碰巧收到已在role属性(您这样说)上排序的数据,那么所需的操作可归结为一个非常简单的.reduce()操作并且可以用O(n)时间复杂度实现如下;

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