JS对树结构进行模糊搜索,支持多关键字多字段搜索以及排序

这篇博客介绍了如何实现一个本地小数据量的搜索过滤功能,支持多关键字搜索、多字段匹配以及按匹配度排序。数据结构为树形,通过递归遍历和循环嵌套实现搜索,同时提供了优化建议,指出大数据量搜索应考虑使用接口。

需求

本地小数据量的搜索过滤,支持⬇️

  • 多关键字搜索
  • 按匹配度进行排序
  • 编号及名称都可搜索

需求描述

1.数据结构为常见的树结构

[
  {
    id: '1',
    name: '山东',
    children: [
      {
        id: '2',
        name: '济南',
        children: [
          {
            id: '3',
            name: '历下',
          },
        ],
      },
      {
        id: '4',
        name: '青岛',
      },
    ],
  },
  {
    id: '5',
    name: '浙江',
  },
  {
    id: '6',
    name: '江苏',
  },
];

2.多关键字以空格隔开,如山 江,能搜到山东,浙江,江苏
3.支持多字段搜索,如1 江,能搜到山东,江苏,浙江
4.支持匹配度排序,如6 江 ,能搜到浙江,江苏,且江苏在浙江前边

PS:我这里的需求是把数据搜索过滤出来之后,平级展示即可,不需要考虑原有的数据结构,如1 南,能搜到山东和济南,这时候返回的数据是平级的。

思路

1.数据肯定是要递归遍历一下
2.定义一个空数组,用来存放符合搜索结果的数据
3.对遍历的每一项进行判断,如果符合搜索结果则把这一项push进第二步定义数组内
4.判断条件里面应该是两个循环,分别是关键字的循环以及多字段的循环
5.循环开始前初始化rank=0,每个字段符合搜索结果,rank++,最后通过rank进行排序

代码

export function localFilterData(allData: any[], searchText: string, matchColumn = ['id', 'name']) {
  // 如果没有搜索内容,直接返回所有数据
  if (searchText === '') return allData;
  // 关键字拆分成数组
  const searchTextArr = searchText.split(' ');
  // 数据项和搜索关键字进行匹配,有符合条件的返回该item,并根据匹配次数,增加rank属性
  const matchResult = (item: Record<string, any>) => {
    let isConform = false;
    let rank = 0;
    searchTextArr.forEach((keyWord) => {
      const reg = new RegExp(keyWord);
      matchColumn.forEach((column) => {
        if (reg.test(item[column])) {
          rank++;
          isConform = true;
        }
      });
    });
    return isConform ? { ...item, rank } : undefined;
  };
  let result: any[] = [];
  // 递归便遍历所有数据
  const recursiveData = (arr: any[]) => {
    arr.forEach((item) => {
      const matchItem = matchResult(item);
      if (matchItem) result.push(matchItem);
      if (item.children instanceof Array && item.children.length > 0) {
        result = recursiveData(item.children);
      }
    });
    return result;
  };
  return recursiveData(allData).sort((a, b) => {
    return b.rank - a.rank;
  });
}

PS:大数据量的搜索还是走接口比较好;这里的搜索逻辑就是普通的循环嵌套,如果要考虑性能,可以研究研究算法了。

感谢观看~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值