2015-06-04 2 views
5

У меня есть массив объектов, как это:Как разделить яваскрипт массива объекта с конкретным условием использования lodash/underscorejs

var data = [ 
{ 
    type : "parent", 
    name : "A" 
}, 
{ 
    type : "child", 
    name : "1" 
}, 
{ 
    type : "child", 
    name : "2" 
}, 
{ 
    type : "parent", 
    name : "B" 
}, 
{ 
    type : "child", 
    name : "3" 
} 
] 

и я хочу, чтобы переместить дочерние объекты в родительские объекты, расщепляется на parrent объекта (там не задан ключ от дочернего объекта, принадлежащий к тому партину). Таким образом, это только отдельный родительский объект. Чтобы быть просто я хочу, чтобы изменить массив в:

[ 
    { 
    type : "parent", 
    name : "A", 
    child: [ 
     { 
      type : "child", 
      name : "1" 
     }, 
     { 
      type : "child", 
      name : "2" 
     } 
    ] 
    }, 
    { 
    type : "parent", 
    name : "B", 
    child: [ 
     { 
      type : "child", 
      name : "3" 
     } 
     ] 
    } 
] 

Я прочитал lodash о chunk, но это не имеет смысла.

+0

Это сокращение. Для этого используйте _.reduce(). –

+1

Вы имеете в виду имя: 1 и 2 вместо aa и ab, правильно? – mplungjan

+0

Прошу прощения за то, что @mplungjan – waskito

ответ

8

Вы можете использовать либо родной Array.prototype.reduce функции или lodash-х reduce:

var data = [ 
{ 
    type : "parent", 
    name : "A" 
}, 
{ 
    type : "child", 
    name : "1" 
}, 
{ 
    type : "child", 
    name : "2" 
}, 
{ 
    type : "parent", 
    name : "B" 
}, 
{ 
    type : "child", 
    name : "3" 
} 
]; 

// If using _.reduce then use: 
// var newData = _.reduce(data, function(arr, el) {...}, []); 
var newData = data.reduce(function(arr, el) { 
    if (el.type === 'parent') { 
    // If el is pushed directly it would be a reference 
    // from the original data object 
    arr.push({type: el.type, name: el.name, child: []}); 
    } 
    else { 
    arr[arr.length - 1].child.push({type: el.type, name: el.name}); 
    } 

    return arr; 
}, []); 
+0

спасибо @JasonCust. Ты обалденный! – waskito

0

Plain Javascript версия:

var newArr = []; 
var j=0; 
var k=0; 
for (var i = 0; i <data.length; i++) { 
    if(data[i].type == 'parent'){ 
     newArr[j] = data[i]; 
     newArr[j].children = []; 
     j++; 
     k=0; 
    } 
    else { 
     data[i].name = newArr[j-1].name.toLowerCase() + String.fromCharCode(k + 97) 
     newArr[j-1].children[k] =data[i]; 
     k++; 
    } 
} 
console.log(newArr) 

Я предполагаю, что здесь, что родитель всегда помещается перед детьми, как это предусмотрено в вашем примере данных.

Кроме того, было бы хорошо, если бы вы могли предотвратить родителей с 26 детьми. Это приведет к тому, что String.fromCharCode(k + 97) напечатает странные символы. Для этого см. http://www.asciitable.com/

2

Вот решение lodash, которое может быть немного понятнее. CodePen

Несколько замечаний:

  • это изменяет поступающий объект данных - если это проблема, которую мы можем бросить в некоторых _.clone() вызовов.
  • Это будет работать только тогда, когда каждый из родителей имеет 26 или меньше детей, из-за name: "ab" шаблона вы выбрали
var lastParent; 
var result = _.chain(data) 
    .groupBy(function (item) { 
    if (item.type === 'parent') lastParent = item.name 
    return lastParent 
    }) 
    .map(function (group) { 
    var parent = _.first(group) 
    parent.child = _.chain(group) 
     .slice(1) 
     .map(function (child, index) { 
     child.name = parent.name.toLowerCase() + String.fromCharCode(index + 97) 
     return child 
     }) 
     .value() 
    return parent 
    }) 
    .value() 

console.log(result) 
0
for (ele in data) 
{ 
    if (!data[ele].hasOwnProperty('child') && data[ele].type=='parent') 
    { 
     data[ele].child = []; 
     while(data[parseInt(ele) + 1] && data[parseInt(ele) + 1].type == 'child') 
     { 
      data[ele].child.push({type: data[parseInt(ele) + 1].type, name:data[parseInt(ele) + 1].name}); 
      data.splice(parseInt(ele) + 1, 1); 
     } 
    } 
} 
console.log(data); 
0

Простая петля:

var current, parent, result = [], i = 0; 

while(current = data[i++]){ 

    if(current.type === "parent"){ 
     current.child = []; 
     result.push(current); 
     parent = current 
    }else{ 
     current.name = (parent.name + String.fromCharCode(parent.child.length + 97)).toLowerCase(); 
     parent.child.push(current) 
    } 

} 

Demo

Смежные вопросы