如何模糊查询多级的JSON数组?

根据 rowList 里的 name 进行模糊查询

[
    {
        rowName:'A',
        rowList:[
            {
                name:'A00001'
            },
            {
                name:'A00002'
            },
            {
                name:'A00003'
            },
        ]
    },
    {
        rowName:'B',
        rowList:[
            {
                name:'B00001'
            },
            {
                name:'B00002'
            },
            {
                name:'B00003'
            },
        ]
    },
    {
        rowName:'C',
        rowList:[
            {
                name:'B00001'
            },
            {
                name:'B00002'
            },
            {
                name:'B00003'
            },
        ]
    }
]

期待结果
输入 a0000 返回结果如下

[
    {
        rowName:'A',
        rowList:[
            {
                name:'A00001'
            },
            {
                name:'A00002'
            },
            {
                name:'A00003'
            },
        ]
    }
]
阅读 2.7k
4 个回答
let value = '001'
let arr = list.reduce((s, v) => {
  let rowList = v.rowList.filter(it => it.name.toLocaleLowerCase().includes(value.toLocaleLowerCase()))
  return rowList.length ? s.push({...v, rowList}) && s : s
}, [])
console.log(arr);

你这个例子不具有代表性呀,
如果 rowName 包含这个字符串,但是 rowList 里面全不包含这个字符串,只返回 { rowName: 'xx' }
或者只有 rowListname 里面包含这个字符串,rowName 不包含,只返回{ rowList: [{...}] }

const filterList = (arr, query) => {
    const filterArr = JSON.parse(JSON.stringify(arr))
    return filterArr.reduce((newArr, item) => {
        const reg = new RegExp(query, 'i') // 忽略大小写
        item.rowList = item.rowList.filter(item => reg.test(item.name))
        if (item.rowList.length) {
            newArr.push(item)
        }
        return newArr
    }, [])
}

这个问题不是“真·多级”,所以两个遍历过滤可以解决:

function filter(list, rowCondition) {
    return list
        .map(it => ({
            ...it,
            rowList: it.rowList.filter(rowCondition)
        }))
        .filter(({ rowList }) => rowList.length);
}

console.dir(filter(data, it => it.name.startsWith("A00")), { depth: null });
// [{
//       rowName: 'A',
//       rowList: [ { name: 'A00001' }, { name: 'A00002' }, { name: 'A00003' } ]
// }]

console.dir(filter(data, it => it.name.endsWith("001")), { depth: null });
// [
//     { rowName: 'A', rowList: [ { name: 'A00001' } ] },
//     { rowName: 'B', rowList: [ { name: 'B00001' } ] },
//     { rowName: 'C', rowList: [ { name: 'B00001' } ] }
// ]

如果是真·多级,也就是树形结果,参阅:javascript - 过滤/筛选树节点 - 边城客栈 - SegmentFault 思否

let letmyJson=[{rowName:'A',rowList:[{name:'A00001'},{name:'A00002'},{name:'A00003'},]},{rowName:'B',rowList:[{name:'B00001'},{name:'B00002'},{name:'B00003'},]},{rowName:'C',rowList:[{name:'B00001'},{name:'B00002'},{name:'B00003'},]}]
let outArray = []
for (let val in myJson) {
    let childObj = myJson[val];
    if (childObj.hasOwnProperty("rowName") && childObj.rowName.toLowerCase() == "a") {
        outArray.push(childObj)
    }
}
alert(JSON.stringify(outArray))
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题