
本教程详细介绍了如何在javascript中处理一个对象数组,从每个对象中移除那些在数组中先前对象中已经出现过的重复键值对。通过构建一个高效的“已见”映射表,我们将逐步指导您实现一个函数,该函数能够生成一个仅包含在各自对象中首次出现的唯一键值对的新对象数组,从而确保数据去重并保持原始结构。
在处理复杂的数据结构时,我们经常会遇到需要去重的情况。本教程关注的是一个特定的去重场景:给定一个包含多个对象的数组,我们希望创建一个新的数组,其中每个对象只保留那些在整个处理过程中首次出现的键值对。这意味着,如果一个 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"
}
];期望输出数组:
立即学习“Java免费学习笔记(深入)”;
[
{
"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)。这个映射表将存储每个键以及该键所对应的值是否已被发现过的信息。
算法步骤如下:
我们可以利用 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"
}
]这个输出与我们预期的结果完全一致,成功地移除了所有重复的键值对。
通过本教程,您已经学会了如何使用 Array.prototype.reduce 和一个自定义的“已见”映射表来高效地从对象数组中提取并保留那些在处理过程中首次出现的键值对。这种模式在处理需要基于历史状态进行数据过滤的场景中非常有用。
以上就是JavaScript:从对象数组中提取具有唯一键值对的元素的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号