从数据中删除叶节点

remove leaf nodes from data

我正在做一个圆形包装,图形中的节点太多,所以我试图通过删除叶节点来减少节点的数量。

我从 api 获得的数据是一个 json 对象,如下所示:


{
    Children: [], 
    Label: "some str", 
    Value: some int, 
    Properties:[]
}

我正在尝试创建一个循环遍历数据的函数,如果对象没有子对象,它就会被删除。这是我要说的

function removeLeaves(data){
let keys = Object.entries(data);
for(let [name,obj] of keys){
    if(name == "Children"){
        if((<Array<any>>obj).length > 0){
            for(let child of (<Array<any>>obj)){

                removeLeaves(child);
            }
        }
        else{
            data = {}; //delete object
        }
    }

  }
}

但由于数据不是引用类型,因此不会保存更改。谁能帮我这个?我正在尝试做类似于 c# removeLeaves(ref data)

的事情

或者有什么方法可以去除 pack 方法中的叶子

var pack = data => d3.pack()
    .size([width, height])
    .padding(5)
    (d3.hierarchy(data, d => d.Children)
     //here some kind of filtering
    .sum(d => {            
        return d.Value;
    })
    .sort((a, b) => b.value - a.value));

我会选择一种方法recursively/programmatically构建所需的数据结构而不是改变现有的输入数据删除不需要的属性 ...

// {Children: [], Label: "some str", Value: some int, Properties:[] }

const data = {
  Label: "root_with_children",
  Value: 1,
  Properties: ["foo", "bar"],
  Children: [{

    Label: "level_1_without_children",
    Value: 2,
    Properties: ["foo", "bar"],
    Children: []
  }, {
    Label: "level_1_with_children",
    Value: 3,
    Properties: ["foo", "bar"],
    Children: [{

      Label: "level_2_without_children",
      Value: 4,
      Properties: ["foo", "bar"],
      Children: []
    }, {
      Label: "level_2_with_children",
      Value: 5,
      Properties: ["foo", "bar"],
      Children: [{

        Label: "level_3_without_children",
        Value: 6,
        Properties: ["foo", "bar"],
        Children: []
      }]
    }]
  }]
};

function isNonEmtyArray(type) {
  return (Array.isArray(type) && (type.length >= 1));
}

function collectItemsWithChildrenOnly(list, item) {
  const { Children } = item;
  if (isNonEmtyArray(Children)) {

    const copy = Object.assign({}, item, { Children: [] });
    list.push(copy);

    Children.reduce(collectItemsWithChildrenOnly, copy.Children);
  }
  return list;
}

let test;

test = [data].reduce(collectItemsWithChildrenOnly, []);
console.log('1st run :: test : ', test);

test = test.reduce(collectItemsWithChildrenOnly, []);
console.log('2nd run :: test : ', test);

test = test.reduce(collectItemsWithChildrenOnly, []);
console.log('3rd run :: test : ', test);

test = test.reduce(collectItemsWithChildrenOnly, []);
console.log('4th run :: test : ', test);

test = test.reduce(collectItemsWithChildrenOnly, []);
console.log('countercheck :: test : ', test);
.as-console-wrapper { min-height: 100%!important; top: 0; }

假设你得到的对象数组 Children 属性 是一个对象数组或一个空的 arr 表示它是一个叶子你可以使用以下函数的组合删除叶子节点

const removeEmptyChildren = obj => obj.Children.length
?
    {...obj,Children:leafRemover(obj.Children)}
:
    undefined


const leafRemover = arr => arr.filter( e => removeEmptyChildren(e) !== undefined)
console.log(leafRemover(data)) // where data is array of objects from the server