Javascript 有效过滤嵌套数组

Javascript 有效过滤嵌套数组,javascript,node.js,arrays,algorithm,Javascript,Node.js,Arrays,Algorithm,我有一个数组形式的大型数据集: [ { id: '9', name: 'Foo', nestedTypes: [ { value: '10025', displayValue: 'Request value A', }, {

我有一个数组形式的大型数据集:

[
        {
            id: '9',
            name: 'Foo',
            nestedTypes: [
                {
                    value: '10025',
                    displayValue: 'Request value A',
                },
                {
                    value: '10027',
                    displayValue: 'Some random request',
                },
            ],
        },
        {
            id: '3',
            name: 'Name B',
            nestedTypes: [
                {
                    displayValue: 'Bar',
                    value: '10026',
                },
                {
                    displayValue: 'Another request within B',
                },
            ],
        },
    ]
在运行文本匹配后,我需要从该数据集中构建一个对象的扁平数组。给定一个字符串,如果它出现在键“name”的值中,则父对象及其所有“nestedTypes”都将包含在结果中。如果它没有出现,我需要在“nestedTypes”中的“displayValue”中搜索匹配项。如果存在匹配项,它将与其父项一起包含在展平数组中

例如,搜索字符串“Foo”,结果:

[{
  label:'Foo',
  value:9 

}, {
  value: '10025',
  label: 'Request value A'
}, {
  value: '10027',
  label: 'Some random request'
}]
[{
  label:'Name B',
  value:3 

}, {
  value: '10026',
  label: 'Bar'
}]
搜索字符串:“栏”,结果:

[{
  label:'Foo',
  value:9 

}, {
  value: '10025',
  label: 'Request value A'
}, {
  value: '10027',
  label: 'Some random request'
}]
[{
  label:'Name B',
  value:3 

}, {
  value: '10026',
  label: 'Bar'
}]
数据集是一个巨大的数组,大约有500个,大约有7个“嵌套类型”

我使用Array.reduce分两步执行此操作:

 const flattenGroupedTypes = (groupedTypes, filterString) => {
        const constructed = groupedTypes.reduce((acc, current) => {
                if (current.name.toLowerCase().includes(filterString.toLowerCase())) {
                    return acc.concat([
                        {
                        label:current.name,
                        value:current.id
                        },
                        ...current.nestedTypes.map(nestedType => ({label:nestedType.displayValue, value:nestedType.value})),
                    ]);
                }
                const nestedTypesMatched = current.nestedTypes.filter(type => type.displayValue.toLowerCase().includes(filterString.toLowerCase()));
                if (nestedTypesMatched.length) {
                    return acc.concat([
                        {
                        label:current.name,
                        value:current.id
                        },
                        ...nestedTypesMatched.map(nestedType => ({label:nestedType.displayValue, value:nestedType.value})),
                        ),
                    ]);
                }
                return acc;
            },
            []
        );
        return constructed;
    };

我能让这个更有效率吗?我似乎找不到更好的算法/方法来减少计算或使其更简单。这对我很重要,因为我正在处理的问题可能很大。

这里有一种方法。我将问题分解为助手/实用程序函数

逻辑与你的没有太大不同,尽管细分情况有所不同。最大的区别是我使用了一个
filterMap
实现,它在一次过程中过滤和映射。我还在顶层使用
flatMap
,而不是
reduce
。这似乎更简单

以下是我的版本:

//实用函数
常量过滤器映射=(f,m)=>(xs)=>
平面图(x=>f(x)?[m(x)]:[])
//辅助函数
const extractRoot=(389;,id,名称,嵌套)=>[
{label:name,value:id},
…nested.map(({value,displayValue})=>({label:displayValue,value}))
]
const extractNested=(str,id,name,nested)=>{
常量结果=过滤器映射(
({displayValue})=>displayValue==str,
({displayValue,value})=>({label:displayValue,value})
)(嵌套)
返回results.length?[{label:name,value:id},…results]:[]
}
//主要功能
常量提取=(str,xs)=>
xs.flatMap({id,name,nestedTypes})=>
(name==str?extractRoot:extractNested)(str,id,name,nestedTypes)
)
//样本数据
const data=[{id:'9',name:'Foo',嵌套类型:[{value:'10025',displayValue:'Request value A'},{value:'10027',displayValue:'Some random Request'}]},{id:'3',name:'name B',嵌套类型:[{displayValue:'Bar',value:'10026',},{displayValue:'B'}内的另一个请求]
//演示
console.log(提取('Foo',数据))
console.log(提取('Bar',数据))

。作为控制台包装{max height:100%!重要;top:0}
要使其有效,您必须删除所有
过滤器
包括
映射
。。。一个简单的
for
循环比这些数组函数快10倍。您的结果与您所说的您想要的结果不匹配。您说过“原始对象”包含在结果中,但它不在显示的结果中,并且您创建了一个名为
label
的对象,您在任何地方都没有提到它。你到底想要什么?你只需要一个循环<代码>for of通常很好(它们经过了积极的优化),但如果遇到性能问题,请使用
for
。旁注:除非您使用预定义的、可重用的reducer函数进行函数编程,
reduce
过于复杂,很容易出错。只需使用一个循环。结果将是一个对象数组。每个对象都有一个标签和一个值键。我在使用嵌套类型时使用“displayValue”作为标签,在拾取父对象时使用“name”作为标签。对于“value”,我使用嵌套类型中的“value”,如果使用父对象,则使用“Id”。