javascript - 如何使用递归过滤所有单个 JSON 数据?

标签 javascript json algorithm

我希望树中的所有单个节点都合并到它的父节点中,但是如果它的子节点包含两个或多个子节点,则没有任何变化。

这是我的数据模型示例:

[{
        name: "HOME",
        value: [{//Only node merged into the parent level
            name: "HOME",
            value: [{//Only node merged into the parent level
                name: "HOME",
                id: '1000'
            }] 
        }]
    }, {
        name: "ARTICLE",
        value: [{
            name: "ARTICLE",
            value: [{
                name: "ARTICLE TYPE 1",
                id: '2001'
            },{
                name: "ARTICLE TYPE 2",
                id: '2002'
            }] 
        },{
            name: "ARTICLE",
            value: [{//Only node merged into the parent level
                name: "ARTICLE TYPE 3",
                id: '2003'
            }] 
        }]
    }]

我要过滤的数据是这样的:

    [{
        name: "HOME",
        id: 1000
    }, {
        name: "ARTICLE",
        value: [{
            name: "ARTICLE",
            value: [{
                name: "ARTICLE TYPE 1",
                id: '2001'
            },{
                name: "ARTICLE TYPE 2",
                id: '2002'
            }] 
        },{
            name: "ARTICLE TYPE 3",
            id: '2003'
        }]
    }]

//更新1: 思路是这样的,但是现在有个问题,发现节点不能回退到原来的节点,只能修改当前父节点:

function filter(data){
    for(var i = 0; i < data.length; i++){
        if( !data[i].value ) continue;

        //Check whether there are child nodes "value" is because it contains a "value" does not exist "id",
        //you must enter a recursive make the following checks
        if( data[i].value.length === 1 && !data[i].value[0].value ) {
            data[i].id = data[i].value[0].id;
            delete data[i].value;
            continue;
        }
        filter( data[i].value );
    }
    return data;
}

我现在直接修改原来的对象,不知道这样做是否合理。

//更新2: 我最后的写法是这样的,结果输出看起来是正确的,但是不确定逻辑是否正确,而且看起来很丑,或者不知道有没有更好的解决方案?

function filter(data, parent){
    for(var i = 0; i < data.length; i++){
        if( data[i].value ) filter( data[i].value, data[i] );

        if( parent && data.length === 1 && !data[i].value ) {
            parent.id = data[i].id;
            delete parent.value;
        }
    }
    return data;
}

最佳答案

一个简单的版本

function merge(node){
    if(node.value){
        var children = node.value.map(merge);
        return children.length === 1?
            children[0]:
            {
                name: node.name,
                value: children
            };
    }
    return node;
}
var result = data.map(merge);

左右:

function cp(a, b){
    for(var k in b){
        if(k === "value" || k in a) continue;
        a[k] = b[k];
    }
    return a;
}

function merge(node){
    if(node.value){
        var children = node.value.map(merge);
        return children.length===1 && !("value" in children[0])?
            cp(children[0], node):
            cp({ value: children }, node);
    }
    return cp({}, node);
}
var result = data.map(merge);

关于javascript - 如何使用递归过滤所有单个 JSON 数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34667885/

相关文章:

javascript - 使用输入在 JavaScript 中分类

javascript - 在 Javascript 中填充 Meta 标记

javascript - ES6 - 在父构造函数方法中获取子类属性

mysql - 更新表时跟踪行中的实际更改

javascript - 使用另一个表单元素的 textarea 值动态更新 h1 元素

java - 由 : com. google.gson.JsonSyntaxException : java. lang.IllegalStateException 引起:预期为 BEGIN_OBJECT,但在第 1 行第 2 列处为 STRING

python - 自定义Python JSON object_hook

java - 使用 Jackson 解析 json

python - 删除除特定值外的多次出现?

c++ - 简单的循环,哪一个我会获得更好的性能,哪一个被推荐?在循环内或循环外定义变量?