javascript - 为什么这些嵌套的 forEach 循环的行为是这样的?
问题描述
我正在尝试构建一个基于地图的 Javascript 生成器,但我面临一个大问题。总而言之,这是预期行为的方案:
A js map named
finalSelection
is created based on user's inputs when one or more items are being selected (html basic select). 该映射由成分(键)组成,对于每种成分,另一个包含其效果(值)的映射。- 它是这样的(例如):
finalSelection = {"Black Pepper": {"Fortify Constitution": 3, "Fortify Constitution": 3, "Resist Fire": 2, "Weakness to Fire": 1, "Resist Acid": 1}, ...};
- 它是这样的(例如):
当该用户单击
generateButton
HTML 按钮时,名为的字段result
应显示基于先前描述的地图的生成结果,如下所示:"You generated a potion ! 'Weakness to necrotics' : 6/10"
生成器背后有一个非常简单的逻辑:
- 如果在用户选择并打包到
finalSelection
地图中的所有成分(html选择选项)中,生成器可以在这些成分中找到两个(或多个)效果出现,它会显示效果的名称和总和两个值:You created a potion ! ${effectName} : ${effectValue1 + effectValue2}
。 - 成分需要是两种(或更多)不同的成分。
为了实现这一点,我构建了一个基于嵌套的“forEach”循环和一些基本的“if...else”语句的生成器:
// Core algorythm of the generation process
function generatePotion() {
finalSelection.forEach(function(ingredientEffects, ingredientName, finalSelection) {
Object.entries(ingredientEffects).forEach(function(effectValue, effectName, ingredientEffects) {
finalSelection.forEach(function(ingredientEffects2, ingredientName2, finalSelection) {
Object.entries(ingredientEffects2).forEach(function(effectValue2, effectName2, ingredientEffects2) {
if (ingredientName !== ingredientName2) {
if (effectName === effectName2) {
potion = `${effectName} : ${effectValue + effectValue2}`;
}
}
})
})
})
})
return potion;
}
还有一个非常简单的“点击”监听器:
// Listen to the state of the 'Generate' button
var generateButton = $('#generateButton');
generateButton.on('click', function() {
if (finalSelection.size !== 0) {
generatePotion();
potion = generatePotion();
result.innerHTML = potion;
} else {
result.innerHTML = "Nothing Selected.";
}
console.log(potion);
});
但我没有得到预期的行为,而不是像Weakness to Necrotics : 6/10
我得到这个:4 : Fortify Investigation,1Weakness to Fire,2
。
这是一个 JSFiddle :
https://jsfiddle.net/d378szxw/
因此,在数小时的头痛之后,我想向社区寻求一些帮助!非常感谢您的宝贵帮助,请原谅法国人可能的拼写错误!
解决方案
我会做这样的事情:
function generatePotion() {
const effectObject = {};
const resultPotion = '';
finalSelection.forEach(function(ingredientEffects, ingredientName) {
Object.keys(ingredientEffects).forEach(effect => {
if (!effectObject[effect]) {
effectObject[effect] = {
value: ingredientEffects[effect],
occurrences: 1
};
} else {
effectObject[effect].occurrences++;
effectObject[effect].values += ingredientEffects[effect];
}
});
});
Object.keys(effectObject).forEach(effect => {
if (effectObject[effect].occurrences > 1) {
resultPotion += `${effect} : ${effectObject[effect].value}`
}
}
return resultPotion;
}
这将遍历 finalSelection 并创建一个具有出现次数和总值的 Effects 对象。你最终想要做什么取决于你,我所做的是将不止一次找到的所有效果及其值连接在一个字符串中。
推荐阅读
- python - 在圆的圆周上绘制点但以椭圆的形式出现
- html - 如何创建或找到适合我网站的壁纸?
- python-3.x - IndexError:从文本文件更新游戏地图时,字符串索引超出范围
- testing - 在 TestCafe 中可以注册 xhr 并用作模拟(自动模拟)
- android - 将应用程序上传到 Google Play 时收到错误消息
- android - 具有多个表的 SQLite DB
- node.js - TypeError:无法读取未定义的属性“firstName”
- android - Recyclerview Adapter crash app 中 Glide 的实现,
- javascript - 为什么曲目名称中的点会混淆通过 Spotify Web API 进行的搜索?
- excel - 简单的 Visual basic If 图像