简体   繁体   English

javascript根据键值过滤嵌套对象

[英]javascript filter nested object based on key value

I wish to filter a nested javascript object by the value of the "step" key: 我希望通过“ 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)});

This just returns the unmodified nested object, even if I put value of filter to 1. does .filter work on nested objects or do I need to roll my own function here, advise and correct code appreciated. 即使我将filter的值设为1,这也只会返回未修改的嵌套对象。.filter是否对嵌套对象起作用,或者我是否需要在此处滚动自己的函数,建议并纠正代码。 cjm 军事审判

Recursive filter functions are fairly easy to create. 递归过滤器函数很容易创建。 This is an example, which strips a JS object of all items defined ["depth","x","x0","y","y0","parent","size"] : 这是一个示例,它剥离了所有定义为["depth","x","x0","y","y0","parent","size"]项目的JS对象:

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;
}

If you would like to filter by something else, just updated the 2nd line with your filter function of choice. 如果您想进行其他过滤,只需使用您选择的过滤功能更新第二行。

Here's the function to filter nested arrays: 这是过滤嵌套数组的函数:

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;
}

The only thing you have to do is to wrap your root object into an array to reach self-similarity. 唯一要做的就是将根对象包装到一个数组中以达到自相似性。 In common, your input array should look like this: 通常,您的输入数组应如下所示:

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

where <...> stands for some properties (in your case those are "name", "step" and "id"), and "children" is an optional service property. 其中<...>代表某些属性(在您的情况下,这些属性是“名称”,“步骤”和“ id”),“子项”是可选的服务属性。 Now you can pass your wrapped object into the filter function alongside a condition callback: 现在,您可以将包装的对象与条件回调一起传递到filter函数中:

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

and you'll get your structure filtered. 然后您的结构将被过滤。 Here are a few more functions to deal with such structures I've just coded for fun: 这里有一些其他函数可以处理我刚刚编写的有趣的此类结构:

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;
}

Usage examples: 用法示例:

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

Likely, the code samples aren't ideal but probably could push someone to the right direction. 代码示例可能不是理想的,但可能会将某人推向正确的方向。

Yes, filter works on one array (list), like the children of one node. 是的, filter可在一个数组(列表)上工作,就像一个节点的孩子一样。 You have got a tree, if you want to search the whole tree you will need to use a tree traversal algorithm or you first put all nodes into an array which you can filter. 您有一棵树,如果要搜索整棵树,则需要使用树遍历算法,或者首先将所有节点放入可以过滤的数组中。 I'm sure you can write the code yourself. 我确定您可以自己编写代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM