簡體   English   中英

如何使用lodash / underscorejs拆分具有特定條件的javascript對象數組

[英]How to split javascript array of object with specific condition using 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對象分割(子對象中沒有給定的鍵屬於哪個parrent)。 所以它只與父對象分開。 為簡單起見,我想將數組更改為:

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

我讀過關於chunk的 lodash,但它沒用。

您可以使用本機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; }, []); console.log(newData); 

更新:使用較新的ES語言功能進行小更改

 const data = [{ type: "parent", name: "A" }, { type: "child", name: "1" }, { type: "child", name: "2" }, { type: "parent", name: "B" }, { type: "child", name: "3" } ]; const newData = data.reduce((arr, el) => { if (el.type === 'parent') { // If el is pushed directly it would be a reference // from the original data object arr.push({...el, child: []}); } else { arr[arr.length - 1].child.push({...el}); } return arr; }, []); console.log(newData); 

這是一個可能更容易理解的lodash解決方案。 CodePen

幾點說明:

  • 這會修改傳入的數據對象 - 如果這是一個問題,我們可以在一些_.clone()調用中拋出。
  • 這僅適用於每個父母有26個或更少的孩子,因為name: "ab"您選擇的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)

普通的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/

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

嘗試簡單的循環:

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

}

演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM