使用Javascript

时间:2018-11-13 18:18:51

标签: javascript data-structures filter

我尝试用JavaScript编写一个函数,该函数通过选定的属性(值)来过滤数组。

但是它仅适用于2级,我不知道我缺少什么。

我要过滤的数据:

  var data = [

    {
        name: "john_pc",
        children: [
            {
                name: "sabrina_pc",
                children: [
                    {
                        name: "sabrina_pc"
                    },
                    {
                        name: "john_pc"
                    }
                ]
            },
            {
                name: "john_pc"
            }
        ]
    },

    {
        name: "sabrina_pc"
    }
]

var data = [ { name: "john_pc", children: [ { name: "sabrina_pc", children: [ { name: "sabrina_pc" }, { name: "john_pc" } ] }, { name: "john_pc" } ] }, { name: "sabrina_pc" } ]

childrenFilter函数:

调用函数:

您可以看到'childrenFilter'获得了一个对象,该键的关键是数据中的属性,而键是我想要保留的值。 const childrenFilter = (childrenData, filters) => { let filteredData = childrenData.filter(item => { for (var property in filters) { var optionalValues = filters[property]; var value = item[property]; if (item.children) { item.children = childrenFilter(item.children, filters); } let hasValue = value == optionalValues; if (hasValue) { return true; } return false; } return false; }, this); return filteredData; }

想要的结果:

let result = childrenFilter(data, { "name": "a1" }); console.log(JSON.stringify(result, null, 2))

  [
    {
        "name": "john_pc",
        "children": [
            {
                "name": "sabrina_pc",
                "children": [
                    {
                        "name": "john_pc"
                    }
                ]
            },
            {
                "name": "john_pc"
            }
        ]
    }
]

2 个答案:

答案 0 :(得分:1)

您的过滤器功能未考虑子元素是否与模式匹配,因此,即使对象的某些子元素与模式匹配,对象本身也会被过滤掉。

以下是说明:

var duplicates = db2.AsEnumerable()
  .GroupBy(r => new
  {
    Tool = r.Field<string>("Tool"),
    Product = r.Field<string>("Product"),
    Time1 = r.Field<DateTime>("Time1"),
    Row = r.Field<Int32>("Row")
  });

foreach (var d in duplicates)  //Iterate through the groups
{
  foreach (var item in d)  //Iterate through the items in a group
  {
    item.Count = d.Count();
  }
}

这应该产生所需的输出:

        {
            name: "a2", // does not match filter {name:'a1} so is removed alongside child objects
            children: [ // gets removed with parent object
                {
                    name: "a2"
                },
                {
                    name: "a1" 
                }
            ]
        }

答案 1 :(得分:1)

您可以从叶子开始为过滤的每个步骤构建新的数组,并检查其中是否包含所需的值。

这种方法会生成新对象,并且不会变异原始数据。

function filter(array, filters) {
    return array.reduce((r, o) => {
        var children = filter(o.children || [], filters);
        return children || Object.entries(filters).every(([k, v]) => o[k] === v)
            ? (r || []).concat(Object.assign({}, o, children && { children }))
            : r;
    }, undefined);
}

var data = [{ name: "a1", children: [{ name: "a2", children: [{ name: "a2" }, { name: "a1" }] }, { name: "a1" }] }, { name: "b1" }];
    
console.log(filter(data, { name: "a1" }));
.as-console-wrapper { max-height: 100% !important; top: 0; }