在数组javascript中使用parentID计算所有子元素

时间:2018-04-30 11:01:25

标签: javascript arrays sorting arraylist tree

我在javascript中有数组。我需要计算父ID。例如id 1是id 2的父亲,id 2是id 3&的父亲。 id 6,id3是id 4的父级,id 4是id 5的父级。所以id的总计数是5.

var arr = [{ "Id": "1", "Parent": "1"},
{ "Id": "2",  "Parent": "1" },
{ "Id": "3",  "Parent": "2"},
{ "Id": "4",  "Parent": "3"},
{ "Id": "5",  "Parent": "4"}, 
{ "Id": "6",  "Parent": "2"}];

我需要结果如:

[{ "Id": "1", count :5},
{ "Id": "2",  "count": "4" },
{ "Id": "3",  "count": "2"},
{ "Id": "4",  "count": "1"},
{ "Id": "5",  "count": "0"},
{ "Id": "6",  "count": "0"}];

这是我的小提琴jsfiddle.net/h5g30bhs

3 个答案:

答案 0 :(得分:1)

使用getterArray.reduce()使用count Object.values()创建对象区域,然后使用Array.map()通过调用getter创建对象。< / p>

实用程序:

  • createCountObj - 使用count getter
  • 创建一个对象

&#13;
&#13;
const arr = [{"Id":"1","Parent":"1"},{"Id":"2","Parent":"1"},{"Id":"3","Parent":"2"},{"Id":"4","Parent":"3"},{"Id":"5","Parent":"4"},{"Id":"6","Parent":"2"}];

// create a count object with children and count getter
const createCountObj = (Id) => ({
  Id,
  children: [],
  get count() {
    // optimization to use cached _count instead of recalculating
    this._count = '_count' in this ? this._count : 
      this.children.length + this.children.reduce((s, { count }) => s + count, 0);
    return this._count;
  }
});
const result = Object.values(arr.reduce((r, o) => {
    // take object if exists, or create new one if not
    r[o.Id] = r[o.Id] || createCountObj(o.Id);
    
    // if the object is not parent of itself
    if (o.Id !== o.Parent) {
      // create a parent if doesn't exist
      if(!r[o.Parent]) r[o.Parent] = createCountObj(o.Parent);
      
      // add to parent
      r[o.Parent].children.push(r[o.Id]);
    } 

    return r;
  }, {}))
  // create final objects by calling the getter of each item
  .map(({ Id, count }) => ({
    Id,
    count
  }));

console.log(result);
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我试了一下。看看它是否适合你:

function convert(input) {
var output = [];
  input.forEach(i => {
    var node = output.find(o => o.Id === i.Parent);
    if (node !== undefined) {
      node.count = "" + (parseInt(node.count, 10) + 1);
    } else {
      output.push({Id: i.Parent, count: "1"})
    }
  })
  return output;
}

需要考虑的一些事项:

  • 你的属性应该都是以小写字母(id而不是Id)开头的
  • 如果算一算,将它们作为数字而不是字符串更好(所以你可以摆脱我使用的parseInt)

答案 2 :(得分:0)

如果您需要帮助,请按照以下方式进行操作,请告知我们。

&#13;
&#13;
const arr = [
  { "Id": "1", "Parent": "1"},
  { "Id": "2",  "Parent": "1" },
  { "Id": "3",  "Parent": "2"},
  { "Id": "4",  "Parent": "3"},
  { "Id": "5",  "Parent": "4"}, 
  { "Id": "22",  "Parent": "22"},//added root item with no children
  { "Id": "6",  "Parent": "2"}
];

const reGroup = data => {
  const grouped = data.filter(x=>x.Id!==x.Parent).reduce(//only child items (id!==Parent)
    (o,item)=>{
      o[item.Parent]=o[item.Parent]||{count:0,children:[]};
      o[item.Parent].count+=1;
      o[item.Id]={count:0,children:[]};
      o[item.Parent].children.push(o[item.Id]);
      return o;
    },
    data.filter(x=>x.Id===x.Parent).reduce(//only root items (Id===Parent)
      (all,item)=>{
        all[item.Id]={count:0,children:[]};
        return all;
      },
      {}
    )
  );//you can console.log(grouped) if you wonder what it is
  const getSum = (item) => {//recursive function to get sum of item.children[x].children[x].count
    return item.children.reduce(
        (sum,item)=>sum+getSum(item),
        item.count
      );
  }
  return Object.keys(grouped).map(
    key=>({Id:key,count:getSum(grouped[key])})
  );
}
console.log(
  reGroup(arr)
  .map(JSON.stringify).join("\n")//add map to make the console log look better
);
&#13;
&#13;
&#13;