写点什么

如何高效的匹配、筛选数据,避免嵌套循环

作者:六哥是全栈
  • 2024-09-11
    广西
  • 本文字数:1727 字

    阅读完需:约 6 分钟

如何高效的匹配、筛选数据,避免嵌套循环

在处理大量数据时,使用嵌套循环来进行数据匹配是非常低效的,尤其是在数据集较大的情况下。利用 Map 结构可以显著提高数据匹配的效率。因为使用循环查找方式的时间复杂度是 O(n),而使用 map 的 has 匹配方式的时间复杂度接近 O(1),这大大提高了数据查找能力,尤其是数据量大的时候效率尤其显著。下面介绍几种方法来避免嵌套循环,提高数据筛选和匹配的性能。

1.数据匹配

假如有两个数组数据 a 和 b,a 数组里面的元素有个状态值字段 status,而 b 数组则存储这个状态值字段的完整信息,我们的需求是为 a 数组的每个元素的状态值字段匹配对应的中文名称来展示(字典翻译)。

无脑实现(嵌套循环匹配)

// 遍历数组 a


for (User user : a) {    // 获取状态值    Integer status = user.getStatus();    // 遍历数组 b    for (DataStatusEnum statusInfo : b) {        // 匹配状态值        if (statusInfo.getValue().equals(status)) {            // 设置中文名            user.setStatusName(statusInfo.getLabel());            break;        }    }}
复制代码

高效实现(利用 map 匹配)

// 遍历数组 b 转换为mapMap<Integer, String> map = new HashMap<>(b.length);for (DataStatusEnum statusInfo : b) {    map.put(statusInfo.getValue(), statusInfo.getLabel());}// 遍历数组 afor (User user : a) {    // 映射中文名    String statusName = map.get(user.getStatus());    // 设置中文名    user.setStatusName(statusName);}
复制代码

js 写法(利用 map)

// 遍历数组 b 转换为mapconst map = new Map<number, string>();for (const statusInfo of b) {    map.set(statusInfo.value, statusInfo.label);}// 遍历数组 afor (const user of a) {    // 映射中文名    const statusName = map.get(user.status);    // 设置中文名    user.statusName = statusName;}
复制代码

js 写法(利用对象)

// 遍历数组 b 转换为对象const map: any = {};for (const statusInfo of b) {    map[statusInfo.value] = statusInfo.label;}// 遍历数组 afor (const user of a) {    // 映射中文名    const statusName = map[user.status];    // 设置中文名    user.statusName = statusName;}
复制代码

2.数据筛选

假如有两个数组数据 a 和 b,a 数组的元素里面有个 id 字段,而 b 数组的元素则有个 aid 字段存储的是 a 数组元素的 id 字段的值,我们的需求是找出在 b 数组中存有其 id 的的所有 a 数组元素。无脑实现(嵌套循环匹配)


a = a.stream().filter(ax -> {    // 获取状态值    Long id = ax.getId();    // 遍历数组 b    for (UserNotice bx : b) {        // 匹配id        if (Objects.equals(id, bx.getAid())) {            return true;        }    }    return false;}).collect(Collectors.toList());
复制代码

高效实现(利用 map 匹配)

// 遍历数组 b 转换为setSet<Long> set = b.stream()    .map(UserNotice::getAid)    .collect(Collectors.toSet());// 筛选数据a = a.stream()    .filter(x -> set.contains(x.getId()))    .collect(Collectors.toList());
复制代码

js 写法(利用 set)

// 遍历数组 b 转换为setconst set = new Set<string>();for (const bx of b) {    set.add(bx.aid);}// 筛选数据a = a.filter(ax => set.has(ax.id))
复制代码

js 写法(利用对象)

// 遍历数组 b 转换为对象const map: any = {};for (const bx of b) {    map[bx.aid] = true;}// 筛选数据a = a.filter(ax => map[ax.id])
复制代码

3.总结

从以上可以看出,我们将 b 数组数据转换为 map 只需遍历遍历一次 b 数组,而后匹配过程基于 has 函数,几乎无循环遍历过程,相比于在 a 数组遍历里面遍历 b 数组效率要高得多,因为嵌套方式是 a 数组有多少元素就要遍历多少次 b 数组,数据量少时体现不出什么,当数据量很大时就会有极大的性能差异,所以开发过程中如果遇到这种需求可以考虑下本文提供的方法。


发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2024-08-28 加入

还未添加个人简介

评论

发布
暂无评论
如何高效的匹配、筛选数据,避免嵌套循环_Java_六哥是全栈_InfoQ写作社区