2015-06-04 21 views
5

Mam tablicę obiektów tak:Jak podzielić javascript tablicę obiektów z szczególny warunek korzystania lodash/underscore.js

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

i chcę przenieść dziecko obiektów do obiektów nadrzędnych, podzielony przez Parrent obiekcie (tam nie jest podanym kluczem z obiektu potomnego, do którego należy potomek). Jest więc oddzielony tylko przez obiekt nadrzędny. Aby być proste Chcę zmienić tablicę na:

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

przeczytałem lodash o chunk ale to nie ma sensu.

+0

Jest to ograniczenie. Użyj _.reduce() do tego. –

+1

masz na myśli imię: 1 i 2 zamiast aa i ab, prawda? – mplungjan

+0

Przepraszam, tak, tęsknie za tym @mplungjan – waskito

Odpowiedz

8

Można użyć natywnej Array.prototype.reduce funkcję lub lodash na 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

dziękuję @JasonCust. Jesteś niesamowity! – waskito

0

Plain wersja 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) 

Zakładam tutaj, że rodzic jest zawsze umieszczony przed dziećmi, jak przewidziano w swoim przykładzie danych.

Byłoby dobrze, gdybyś mógł zapobiec rodzicom z 26+ dziećmi. To spowoduje, że String.fromCharCode(k + 97) będzie drukować dziwne znaki. Patrz: http://www.asciitable.com/

2

Oto rozwiązanie dla loży, które może być nieco łatwiejsze do zrozumienia. CodePen

Kilka uwag:

  • ten modyfikuje przychodzącego obiektu danych - jeśli to jest problem możemy wrzucić w niektórych _.clone() połączeń.
  • ta będzie działać tylko wtedy, gdy każde z rodziców ma 26 lub mniej dzieci, ze względu na name: "ab" wzoru, który wybrałeś
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

Wypróbuj prostą pętlę:

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