
本文旨在指导读者如何在 javascript 中有效地根据两个对象的键值进行比较并计算特定属性的总和。我们将探讨多种实现策略,包括利用 `reduce` 方法进行链式操作,以及通过构建查找表或键集合来简化逻辑,最终实现对匹配项分数的累加。
在 JavaScript 开发中,我们经常需要处理结构化数据,并根据特定条件对数据进行聚合。一个常见的场景是,我们有两个对象:一个包含用户的选择或答案,另一个则存储了所有可能选项对应的分数。我们的目标是根据用户的选择,从分数对象中找出对应的分数并计算总和。
假设我们有以下两个 JavaScript 对象:
示例数据:
const values = {
Q1: {
Q1A1: "Yes",
},
Q2: {
Q2A1: "Yes",
},
Q3: {
Q3A2: "No",
},
};
const points = {
Q1A1: 41,
Q1A2: 0,
Q2A1: 19,
Q2A2: 0,
Q3A1: 25,
Q3A2: 0,
};根据上述数据,如果用户选择了 Q1A1 ("Yes") 和 Q2A1 ("Yes"),并且 Q3A2 ("No") 不计入分数,那么期望的总和是 points.Q1A1 (41) + points.Q2A1 (19) = 60。
立即学习“Java免费学习笔记(深入)”;
接下来,我们将介绍几种实现此计算的方法。
这种方法利用 Array.prototype.reduce() 的强大功能,通过两次迭代来聚合数据。外层 reduce 遍历 values 对象的问题,内层 reduce 遍历每个问题下的答案。
const values = {
Q1: { Q1A1: "Yes" },
Q2: { Q2A1: "Yes" },
Q3: { Q3A2: "No" },
};
const points = {
Q1A1: 41,
Q1A2: 0,
Q2A1: 19,
Q2A2: 0,
Q3A1: 25,
Q3A2: 5, // 即使有分,如果 'No' 也不计
};
const total = Object.values(values) // 获取 values 对象的所有值 (即 Q1, Q2, Q3 对应的子对象)
.reduce((acc, cur) => { // 外层 reduce 累加每个问题下的分数
return acc + Object.entries(cur) // 获取当前问题子对象的所有键值对 (如 ['Q1A1', 'Yes'])
.reduce((accInner, [key, val]) => { // 内层 reduce 处理单个答案
// 检查答案值是否不为 'No' 且 points 对象中存在对应的键
if (val !== 'No' && points[key]) {
return accInner + points[key]; // 如果满足条件,累加对应的分数
}
return accInner; // 否则不累加
}, 0); // 内层 reduce 的初始累加值为 0
}, 0); // 外层 reduce 的初始累加值为 0
console.log(total); // 输出: 60解释:
这种方法首先从 values 对象中创建一个简化的查找表,只包含需要计分的答案 ID。然后,利用这个查找表对 points 对象进行过滤和求和。这种方法通常更易于阅读和理解。
const values = {
Q1: { Q1A1: "Yes" },
Q2: { Q2A1: "Yes" },
Q3: { Q3A2: "No" },
};
const points = {
Q1A1: 41,
Q1A2: 0,
Q2A1: 19,
Q2A2: 0,
Q3A1: 25,
Q3A2: 5,
};
// 1. 构建一个查找表,只包含需要计分的答案ID
const lookup = Object.values(values).reduce((acc, cur) => {
const [key, val] = Object.entries(cur)[0]; // 每个子对象只有一个键值对
if (val === "Yes") { // 只将值为 "Yes" 的答案加入查找表
acc[key] = true; // 可以是任何真值,这里用 true 表示存在
}
return acc;
}, {});
console.log("Lookup table:", lookup); // 输出: { Q1A1: true, Q2A1: true }
// 2. 遍历 points 对象,根据查找表过滤并求和
const totalPoints = Object.entries(points) // 获取 points 对象的所有键值对
.filter(([key, score]) => lookup[key]) // 过滤:只保留在 lookup 表中存在的键
.reduce((sum, [key, score]) => sum + score, 0); // 求和:累加过滤后的分数
console.log(totalPoints); // 输出: 60解释:
如果 values 对象中答案的值(如 "Yes" / "No")不影响是否计分,而仅仅是键的存在决定是否计分,或者我们只需要收集所有选定的答案 ID,可以使用 Set 来存储这些键,从而提高查找效率。
const values = {
Q1: { Q1A1: "Yes" },
Q2: { Q2A1: "Yes" },
Q3: { Q3A2: "No" }, // 这里的 "No" 依然会被提取键,如果逻辑需要
};
const points = {
Q1A1: 41,
Q1A2: 0,
Q2A1: 19,
Q2A2: 0,
Q3A1: 25,
Q3A2: 5,
};
// 1. 提取所有需要计分的答案ID到一个 Set 中
const selectedAnswerKeys = new Set(
Object.values(values).map(question => Object.keys(question)[0])
);
console.log("Selected Answer Keys:", selectedAnswerKeys); // 输出: Set(3) { 'Q1A1', 'Q2A1', 'Q3A2' }
// 2. 遍历 points 对象,根据 Set 过滤并求和
const totalSum = Object.entries(points)
.filter(([key, score]) => selectedAnswerKeys.has(key)) // 过滤:只保留在 Set 中存在的键
.reduce((acc, [key, score]) => acc + score, 0); // 求和
console.log(totalSum); // 输出: 65 (因为 Q3A2 即使是 "No",其键也被提取并计分了 5)注意: 此方法默认只要 values 对象中存在某个答案 ID,就将其计入总和,而不考虑其关联的 "Yes" / "No" 状态。如果需要考虑状态,应结合方法二的逻辑。
本文介绍了三种在 JavaScript 中根据键值比较两个对象并计算总和的方法:
选择建议:
在实际开发中,请根据您的具体业务逻辑和团队的代码风格偏好来选择最合适的方法。同时,始终考虑代码的可读性、可维护性以及在处理大量数据时的性能表现。
以上就是如何在 JavaScript 中根据键值比较两个对象并计算总和的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号