新闻中心

J*aScript:从对象数组中提取具有唯一键值对的元素

2025-12-04
浏览次数:
返回列表

JavaScript:从对象数组中提取具有唯一键值对的元素

本教程详细介绍了如何在j*ascript中处理一个对象数组,从每个对象中移除那些在数组中先前对象中已经出现过的重复键值对。通过构建一个高效的“已见”映射表,我们将逐步指导您实现一个函数,该函数能够生成一个仅包含在各自对象中首次出现的唯一键值对的新对象数组,从而确保数据去重并保持原始结构。

理解问题与目标

在处理复杂的数据结构时,我们经常会遇到需要去重的情况。本教程关注的是一个特定的去重场景:给定一个包含多个对象的数组,我们希望创建一个新的数组,其中每个对象只保留那些在整个处理过程中首次出现的键值对。这意味着,如果一个 key: value 对已经在数组中的某个先前对象中出现过,那么它在当前对象中就应该被移除。

让我们通过一个示例来具体说明:

原始输入数组:

const arr1 = [
  {
    "Param1": "20",
    "Param2": "8",
    "Param3": "11",
    "Param4": "4",
    "Param5": "18",
    "Param6": "20",
    "Param7": "8"
  },
  {
    "Param6": "21",
    "Param7": "8",
    "Param8": "11",
    "Param9": "4",
    "Param10": "18"
  },
  {
    "Param1": "20",
    "Param2": "8",
    "Param3": "10"
  }
];

期望输出数组:

[
  {
    "Param1": "20",
    "Param2": "8",
    "Param3": "11",
    "Param4": "4",
    "Param5": "18",
    "Param6": "20",
    "Param7": "8"
  },
  {
    "Param6": "21", // Param6: "20" 已在第一个对象中出现,但 Param6: "21" 是新的
    "Param8": "11",
    "Param9": "4",
    "Param10": "18"
  },
  {
    "Param3": "10" // Param1: "20" 和 Param2: "8" 已在第一个对象中出现
  }
]

可以看到,在第二个对象中,"Param7": "8" 被移除了,因为它在第一个对象中已经出现过。同样,在第三个对象中,"Param1": "20" 和 "Param2": "8" 被移除,而 "Param3": "10" 被保留,因为它与第一个对象中的 "Param3": "11" 键相同但值不同,且 "Param3": "10" 之前未出现过。

核心算法思路

要实现上述去重逻辑,我们需要一个机制来“记住”所有已经处理过的键值对。最有效的方法是使用一个“已见”映射表(seen map)。这个映射表将存储每个键以及该键所对应的值是否已被发现过的信息。

算法步骤如下:

Tunee AI Tunee AI

新一代AI音乐智能体

Tunee AI 1104 查看详情 Tunee AI
  1. 初始化 seen 映射表: 创建一个空的 seen 对象(或 Map),其结构为 Record>,即 seen[key][value] = true 表示该键值对已被发现。
  2. 初始化 result 数组: 创建一个空的数组来存放处理后的新对象。
  3. 遍历输入数组: 逐个处理 arr1 中的每个对象。
  4. 处理当前对象: 对于每个对象:
    • 创建一个新的空对象 currentUniqueObject。
    • 遍历当前对象中的所有键值对。
    • 对于每个键 key 和值 value:
      • 首先,检查 seen[key] 是否已存在。如果不存在,则初始化 seen[key] 为一个空对象 {}。
      • 接着,检查 seen[key][value] 是否为 true。
        • 如果为 true,表示这个 key: value 对之前已经出现过,因此我们忽略它。
        • 如果为 false 或 undefined,表示这个 key: value 对是首次出现。
          • 将其添加到 currentUniqueObject 中。
          • 将 seen[key][value] 设置为 true,标记为已见。
  5. 添加结果: 将 currentUniqueObject 添加到 result 数组中。
  6. 返回 result: 遍历完成后,返回 result 数组。

J*aScript 实现

我们可以利用 Array.prototype.reduce 方法来优雅地实现这个算法,它允许我们迭代数组并累积一个单一的结果(在这里是 seen 映射表和 result 数组的组合)。

/**
 * 从对象数组中移除在先前对象中已出现过的重复键值对。
 *
 * @param arr 输入的对象数组,每个对象包含字符串键和字符串值。
 * @returns 包含唯一键值对的新对象数组。
 */
const removeDuplicates = (arr: Record<string, string>[]): Record<string, string>[] => {
    // 使用 reduce 方法来累积 'seen' 映射和 'result' 数组
    return arr.reduce<{
        seen: Record<string, Record<string, boolean>>; // 存储已见键值对的映射
        result: Record<string, string>[];              // 存储处理后的结果数组
    }>(
        (accumulator, currentItem) => {
            // 对于当前对象,筛选出唯一的键值对
            const uniqueItem = Object.fromEntries(
                Object.entries(currentItem).filter(([key, value]) => {
                    // 确保 seen[key] 存在,如果不存在则初始化为 {}
                    accumulator.seen[key] = accumulator.seen[key] ?? {};

                    // 检查当前键值对是否已在 'seen' 映射中
                    if (accumulator.seen[key][value]) {
                        // 如果已见,则过滤掉(返回 false)
                        return false;
                    }

                    // 如果未见,则标记为已见(设置为 true)
                    accumulator.seen[key][value] = true;
                    // 并保留该键值对(返回 true)
                    return true;
                }),
            );
            // 将处理后的唯一对象添加到结果数组中
            accumulator.result.push(uniqueItem);
            return accumulator;
        },
        // reduce 的初始值:一个包含空 'seen' 映射和空 'result' 数组的对象
        { seen: {}, result: [] },
    ).result; // 最后返回累加器中的 'result' 数组
};

示例用法

现在,让我们将 removeDuplicates 函数应用于我们之前的示例数据:

const arr1 = [
  {
    "Param1": "20",
    "Param2": "8",
    "Param3": "11",
    "Param4": "4",
    "Param5": "18",
    "Param6": "20",
    "Param7": "8"
  },
  {
    "Param6": "21",
    "Param7": "8",
    "Param8": "11",
    "Param9": "4",
    "Param10": "18"
  },
  {
    "Param1": "20",
    "Param2": "8",
    "Param3": "10"
  }
];

const uniqueArray = removeDuplicates(arr1);
console.log(JSON.stringify(uniqueArray, null, 2));

输出结果:

[
  {
    "Param1": "20",
    "Param2": "8",
    "Param3": "11",
    "Param4": "4",
    "Param5": "18",
    "Param6": "20",
    "Param7": "8"
  },
  {
    "Param6": "21",
    "Param8": "11",
    "Param9": "4",
    "Param10": "18"
  },
  {
    "Param3": "10"
  }
]

这个输出与我们预期的结果完全一致,成功地移除了所有重复的键值对。

注意事项与总结

  1. 数据类型限制: 本实现假设对象的值是字符串。如果值可以是其他类型(如数字、布尔值、对象等),seen 映射的键(value 部分)可能需要进行调整,例如使用 JSON.stringify 来确保唯一性,但这会带来性能开销。对于原始类型(字符串、数字等),当前方法是高效的。
  2. 时间复杂度: 算法的时间复杂度大致为 O(N * K),其中 N 是输入数组中对象的数量,K 是每个对象中键值对的平均数量。这是因为我们需要遍历每个对象,并对每个对象的每个键值对进行查找和插入操作。
  3. 空间复杂度: 空间复杂度主要取决于 seen 映射表的大小,它将存储所有不重复的键值对。在最坏情况下(所有键值对都不同),空间复杂度为 O(N * K)。
  4. 不可变性: removeDuplicates 函数返回一个全新的数组和全新的对象,不会修改原始输入 arr1,这符合函数式编程的良好实践。

通过本教程,您已经学会了如何使用 Array.prototype.reduce 和一个自定义的“已见”映射表来高效地从对象数组中提取并保留那些在处理过程中首次出现的键值对。这种模式在处理需要基于历史状态进行数据过滤的场景中非常有用。

以上就是J*aScript:从对象数组中提取具有唯一键值对的元素的详细内容,更多请关注其它相关文章!


# 遍历  # 温州网站建设方案开发  # 天津佰蓝网站建设费用  # 专注营销推广哪家服务好  # 杭州专业的网站建设价格  # 密云营销型网站推广  # 惠州环保seo排名前十  # 阿坝模版网站建设公司  # 网站海外推广公司价格  # 武汉视频网站优化方案  # 邵阳公司网站seo  # 创建一个  # 递归  # javascript  # 首次  # 第一个  # 移除  # 已见  # 组中  # 象中  # 键值  # red  # 键值对  # json  # js  # java 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Discord Slash 命令响应超时问题的异步解决方案  Typer应用中灵活处理命令行参数的令牌化与解析  AO3最新入口2025公告_AO3中文官网合集  如何为你的Composer包编写自动化测试_集成PHPUnit到Composer的scripts工作流  支付宝如何设置安全保护_支付宝安全设置的全面教程  AO3镜像入口大全 AO3网页版内容访问全集  响应式CSS Grid布局:优化网格项在小屏幕下的堆叠与宽度适配  多闪网页版在线观看免费入口_多闪官网访问入口  如何设置Windows Defender的定时扫描_计划任务实现自动杀毒【安全】  Safari浏览器输入栏卡顿如何解决 Safari搜索建议与缓存清理  ExcelARRAYTOTEXT函数怎么自定义分隔符输出数组文本_ARRAYTOTEXT实现动态生成SQL语句  处理动态列数据:J*a ArrayList的正确初始化与字符累加教程  Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑  12306选座如何查看座位示意图_12306座位示意图解读与使用  c++ 获取系统当前时间 c++时间戳获取方法  PySpark中从现有列右侧提取可变长度字符创建新列的教程  Pyrogram与g4f集成:异步编程实践与常见错误解决  C++20的source_location是什么_C++在编译期获取源码位置信息用于日志和断言  蛙漫官网漫画入口地址_蛙漫在线畅读无广告弹窗  qq浏览器如何查看和导出已保存的密码 qq浏览器密码管理器数据备份教程  Python中如何避免重复条件判断:利用数据结构实现动态逻辑  包子漫画官方网站阅读入口-包子漫画在线漫画官网直达链接  汽水音乐车机版横屏版7.1 汽水音乐车机版横屏版下载入口  Adobe PDF表单中利用J*aScript解析与格式化日期组件的教程  《噬血代码2》新预告片发布 展示游戏剧情  手机屏幕碎了但能正常使用怎么办 手机外屏碎裂的修复建议  红果短剧网页版官网入口 官方最新网址发布  qq邮箱日历功能怎么用_创建日程与会议邀请的技巧  QQ网页版官方账号入口 QQ网页版网页版登录指南  从OpenAI API响应中高效提取生成文本  自定义Bag-of-Words实现:处理带负号的词汇权重  CSS自定义字体样式被系统字体替换怎么办_font-face方式指定font-display控制渲染策略  必由学官方登录入口 必由学教师学生账号快速访问  mc.js免安装版 mc.js一键畅玩入口  如何在复杂的电商平台中优雅地管理共享资源并确保正确重定向,使用spryker-shop/resource-share-page模块助你一臂之力  Go语言HTML解析:利用Goquery精准获取指定元素内容  Yandex免登录官网入口_俄罗斯Yandex搜索引擎直达链接  提升Kafka消费者健壮性:会话超时处理与消息处理语义  天眼查企业查询官网入口 天眼查官方网页版查询  SteamMachine定价或为699美元 大家想入手吗?  微博网页版怎么开启两步验证_微博网页版账号安全两步验证设置方法  c++中为什么推荐使用using替代typedef_c++现代化类型别名  移动端XML文件怎么转换成Excel 手机和平板上的解决方案  R星幕后开发视频泄露 包含《GTA6》等多款大作  漫蛙Manwa2官网入口地址分享 漫蛙漫画PC版永久访问通道  谷歌学术网站直达地址 谷歌学术搜索网页版一键进入  J*a递归快速排序中静态变量导致数据累积问题的解决方案  解决Rails应用中内容错位与Turbo警告:meta标签误用导致富文本渲染异常  神庙逃亡小游戏在线玩 神庙逃亡小游戏入口  德邦快递查询平台 德邦快递物流信息查询入口 

搜索