3

我希望通过“step”键的值过滤嵌套的 javascript 对象:

var data = {
"name": "Root",
"step": 1,
"id": "0.0",   
"children": [
    {
    "name": "first level child 1",
    "id": "0.1",
    "step":2,
    "children": [
        {
        "name": "second level child 1",
        "id": "0.1.1",
        "step": 3,
        "children": [
            {
            "name": "third level child 1",
            "id": "0.1.1.1",
            "step": 4,
            "children": []},
        {
            "name": "third level child 2",
            "id": "0.1.1.2",
            "step": 5,
            "children": []}

        ]},
                ]}
]

};

var subdata = data.children.filter(function (d) {
        return (d.step <= 2)});

这只是返回未修改的嵌套对象,即使我将过滤器的值设置为 1。.filter 是否适用于嵌套对象,或者我是否需要在此处滚动我自己的函数,建议并更正代码。cjm

4

3 回答 3

2

递归过滤器函数很容易创建。这是一个示例,它剥离了所有已定义项的 JS 对象["depth","x","x0","y","y0","parent","size"]

function filter(data) {
  for(var i in data){
    if(["depth","x","x0","y","y0","parent","size"].indexOf(i) != -1){
       delete data[i]; 
    } else if (i === "children") {
      for (var j in data.children) {
        data.children[j] = filter(data.children[j])
      }
    }  
  }
  return data;
}

如果您想通过其他方式进行过滤,只需使用您选择的过滤功能更新第二行。

于 2014-03-13T04:51:05.600 回答
1

这是过滤嵌套数组的函数:

const filter = arr => condition => {
    const res = [];
    for (const item of arr) {
        if (condition(item)) {
            if (!item.children) {
                res.push({ ...item });
            } else {
                const children = filter(item.children)(condition);
                res.push({ ...item, children })
            }
        }
    }
    return res;
}

您唯一需要做的就是将根对象包装到一个数组中以达到自相似性。通常,您的输入数组应如下所示:

data = [
    { <...>, children: [
        { <...>, children: [...] },
        ...
    ] },
    ...
]

其中 <...> 代表一些属性(在您的情况下是“名称”、“步骤”和“id”),而“孩子”是可选的服务属性。现在您可以将包装的对象与条件回调一起传递给过滤器函数:

filter(data)(item => item.step <= 2)

你会得到你的结构过滤。这里还有一些函数可以处理我刚刚编写的有趣的结构:

const map = arr => f => {
    const res = [];
    for (const item of arr) {
        if (!item.children) {
            res.push({ ...f({ ...item }) });
        } else {
            res.push({ ...f({ ...item }), children: map(item.children)(f) });
        }
    }
    return res;
}

const reduce = arr => g => init => {
    if (!arr) return undefined;
    let res = init;
    for (const item of arr) {
        if (!item.children) {
            res = g(res)({ ...item });
        } else {
            res = g(res)({ ...item });
            res = reduce(item.children)(g)(res);
        }
    }
    return res;
}

使用示例:

map(data)(item => ({ step: item.step }))
reduce(data)($ => item => $ + item.step)(0)

可能,代码示例并不理想,但可能会将某人推向正确的方向。

于 2017-09-25T17:53:19.397 回答
-2

是的,filter适用于一个数组(列表),就像一个节点的孩子一样。你有一棵树,如果你想搜索整棵树,你需要使用树遍历算法,或者你首先将所有节点放入一个可以过滤的数组中。我相信您可以自己编写代码。

于 2012-11-15T23:15:31.180 回答