2017-06-07 73 views
3

我有一個大對象(1500+)和對象匹配其中一個屬性。所以可以減少對象的總數量,例如以獲得更好的ng-repeat性能。 我對AngularJS和JS本身很陌生,所以非常感謝幫助!AngularJS在屬性上組合數組中的對象

我的對象的陣列(簡化的)

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

你總是收到排序的'role'財產的對象像在您的示例數據?如果是這樣,這是一個有價值的信息,並可以大大簡化代碼。 – Redu

+0

@Redu其實我呢!這將如何簡化事情? – DTR9000

+0

那麼你可以通過使用一個'.reduce()'操作在O(n)時間內做到這一點。請參閱下面的答案。 – Redu

回答

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)

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

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

正如我在我的評論中提到,如果你碰巧收到已經排好序的role屬性數據(你這麼說),那麼所需的操作歸結爲非常簡單的操作,並且可以用如下的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; }