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

感谢观看~

你可能感兴趣的:(JS,javascript,前端)