在对象内部迭代数组并相应地添加属性

时间:2018-12-06 03:12:52

标签: javascript arrays object recursion

所以,我对递归有问题,这是数据:

->>

我想做的是对此进行迭代,并将let data = { label: "Root", datasets: [ { label: "Parent 1" datasets: [ { label: "Child 1", dataMax: 100, datasets: 30 }, { label: "Child 2", dataMax: 30, datasets: 30 } ] }, { label: "Parent 2", dataMax: 50, datasets: 30 } ] }; 和数据的属性放到每个没有dataMax的父母中,如果父级有两个或多个子级,dataMax将具有其子级的总值。

请注意,dataMax的深度和长度是随机的。

这是我尝试过的:

data

我设法深入了解了,但是我似乎无法回到根源,我觉得我错过了一些东西,但似乎找不到。我做错了什么?

所需的输出:

let data = {
    label: "Root",
    datasets: [
        {
            label: "Parent 1",
            datasets: [
                {
                    label: "Child 1",
                    dataMax: 100,
                    datasets: 30
                },
                {
                    label: "Child 2",
                    dataMax: 30,
                    datasets: 30
                }
            ]
        },
        {
            label: "Parent 2",
            dataMax: 50,
            datasets: 30
        }
    ]
};

let setDatas = function(x, i, p){
    if (x == undefined) {
        console.log("--- This is x==undefined ---");
        return 1;
    } else if (Array.isArray(x.datasets)) {
        console.log("-------------- " + x.label + ", datasets[" + [i] + "]:");
        console.log(x.datasets[i]);
        return setDatas(x.datasets[i], i, x);
    } else {
        console.log("It's not an Array");
        ++i;
        return setDatas(p, i, p);
    }
}

setDatas(data, 0);

先谢谢了。随时询问更多信息。

3 个答案:

答案 0 :(得分:1)

在您的实际功能中,您没有在data.datasets上进行迭代,只是在检查给定的data,需要遍历嵌套的data.datasets

您可以结合使用 Array#map() Array#reduce() 这样的方法:

function getDataMax(data) {
  if (data.datasets && Array.isArray(data.datasets)) {
    data.datasets = data.datasets.map(x => {
      if (!x.dataMax) {
        if (Array.isArray(x.datasets)) {
          //If inner datasets is an array do the recursive call
          getDataMax(x);
        }
      }
      return x;
    });
  }
  if (!data.dataMax)
    data.dataMax = data.datasets.map(x => x.dataMax).reduce((a, b) => (a + b));
}

演示:

let data = {
  label: "Root",
  datasets: [{
      label: "Parent 1",
      datasets: [{
          label: "Child 1",
          dataMax: 100,
          datasets: 30
        },
        {
          label: "Child 2",
          dataMax: 30,
          datasets: 30
        }
      ]
    },
    {
      label: "Parent 2",
      dataMax: 50,
      datasets: 30
    }
  ]
};


function getDataMax(data) {
  if (data.datasets && Array.isArray(data.datasets)) {
    data.datasets = data.datasets.map(x => {
      if (!x.dataMax) {
        if (Array.isArray(x.datasets)) {
          getDataMax(x);
        }
      }
      return x;
    });
  }
  if (!data.dataMax)
    data.dataMax = data.datasets.map(x => x.dataMax).reduce((a, b) => (a + b));
}
getDataMax(data);
console.log(data)

答案 1 :(得分:0)

看看是否可行:

data = {
    label: "Root",
    datasets: [{
        label: "Parent 1",
        datasets: [{
            label: "Child 1",
            dataMax: 100,
            datasets: 30
        }, {
            label: "Child 2",
            dataMax: 30,
            datasets: 30
        }]
    }, {
        label: "Parent 2",
        dataMax: 50,
        datasets: 30
    }]
}

function setData(data) {
    if (Array.isArray(data.datasets)) {
        let childMax = 0;

        for (let i = 0; i < data.datasets.length; i++) {
            childMax += setData(data.datasets[i]);
        }

        if (data.dataMax === undefined) {
            data.dataMax = childMax;
        }
    }

    return data.dataMax;
}

setData(data);

答案 2 :(得分:0)

您可以使用.reduce方法来保留原始数据

    const datasets = [
            {
                label: "Parent 1",
                datasets: [
                    {
                        label: "Child 1",
                        dataMax: 100,
                        datasets: 30
                    },
                    {
                        label: "Child 2",
                        dataMax: 30,
                        datasets: 30
                    }
                ]
            },
            {
                label: "Parent 2",
                dataMax: 50,
                datasets: 30
            }
        ]; 
    
    
    const redfinedDataset = datasets.reduce( (prev, curr) => {
      if(curr.dataMax) { return prev.concat([curr]);}  
      else {
           if(curr.datasets.length >0) {
            const dataMax = curr.datasets.reduce( (pds, cds) => pds += cds.dataMax, 0);
            const nds = Object.assign(curr, {dataMax});
            return prev.concat([nds]);
           }
         }
    }, []);
    
    console.log(redfinedDataset);