如何在不使用 map() 数组方法的情况下获得相同的结果?在这里使用 map() 数组方法的意义到底是什么?
How can I achieve the same outcome without using map() array method? What exactly is the significance of using map() array method here?
可在此处找到源内容:https://github.com/LinkedInLearning/javascript-essential-training-2832077/tree/main/08_17。有问题的代码就是这个块:
import backpackObjectArray from "./components/data.js";
const content = backpackObjectArray.map((backpack)=>{
let backpackArticle = document.createElement("article");
backpackArticle.classList.add("backpack");
// Set article ID to the backpack.id property
backpackArticle.setAttribute("id", backpack.id);
backpackArticle.innerHTML=`
<figure class="backpack__image">
<img src=${backpack.image} alt="" />
</figure>
<h1 class="backpack__name">${backpack.name}</h1>
<ul class="backpack__features">
<li class="packprop backpack__volume">Volume:<span> ${
backpack.volume
}l</span></li>
<li class="packprop backpack__color">Color:<span> ${
backpack.color
}</span></li>
<li class="backpack__age">Age:<span> ${backpack.backpackAge()} days old</span></li>
<li class="packprop backpack__pockets">Number of pockets:<span> ${
backpack.pocketNum
}</span></li>
<li class="packprop backpack__strap">Left strap length:<span> ${
backpack.strapLength.left
} inches</span></li>
<li class="packprop backpack__strap">Right strap length:<span> ${
backpack.strapLength.right
} inches</span></li>
<li class="feature backpack__lid">Lid status:<span> ${
backpack.lidOpen ? "open" : "closed"
}</span></li>
</ul>
`;
return backpackArticle;
})
const main = document.querySelector(".maincontent");
content.forEach((backpack)=>{
main.append(backpack);
}
)
本质上,是不是只用forEach循环就可以输出和我们使用map()数组方法一样的结果,即为每个对象输出一篇HTML篇文章?
*Pseudo-code* Array.prototype.map(function(ea){return backpackArticle})
将简单地创建一个新数组并在每次迭代中包含您 return 的任何内容。
您可以通过其他方式实现相同的目的,但是,如前所述,需要更多代码。实际上,本例中的 'significance' 只是用更少的代码实现了预期的结果。
我认为在您的示例中,它是显式创建一个新数组,然后使用 forEach 将每个 backpackArticle
显式附加到 <main>
。您可以跳过使用 map 创建新数组。
如果愿意,您绝对可以使用 forEach 循环,只是代码会稍有不同。如果您喜欢新代码的外观,则无需使用地图。
import backpackObjectArray from "./components/data.js";
const main = document.querySelector(".maincontent");
backpackObjectArray.forEach((backpack) => {
let backpackArticle = document.createElement("article");
backpackArticle.classList.add("backpack");
// Set article ID to the backpack.id property
backpackArticle.setAttribute("id", backpack.id);
backpackArticle.innerHTML = `
<figure class="backpack__image">
<img src=${backpack.image} alt="" />
</figure>
<h1 class="backpack__name">${backpack.name}</h1>
<ul class="backpack__features">
<li class="packprop backpack__volume">Volume:<span> ${
backpack.volume
}l</span></li>
<li class="packprop backpack__color">Color:<span> ${
backpack.color
}</span></li>
<li class="backpack__age">Age:<span> ${backpack.backpackAge()} days old</span></li>
<li class="packprop backpack__pockets">Number of pockets:<span> ${
backpack.pocketNum
}</span></li>
<li class="packprop backpack__strap">Left strap length:<span> ${
backpack.strapLength.left
} inches</span></li>
<li class="packprop backpack__strap">Right strap length:<span> ${
backpack.strapLength.right
} inches</span></li>
<li class="feature backpack__lid">Lid status:<span> ${
backpack.lidOpen ? "open" : "closed"
}</span></li>
</ul>
`;
main.append(backpackArticle);
});
编辑
抱歉,我似乎没有足够仔细地阅读您的问题。在您的情况下,是的,您可以将 .map
与 .forEach
互换并直接附加创建的元素而不将它们存储在中间数组中。
但是,我将保留其余部分,也许有人觉得它有用。
作为一个比较笼统的回答,“是的,您可以使用 .forEach
并获得相同的结果”。你也可以用 .reduce
来完成。但是,如果您想从源列表中获得结果列表(如您的示例所示),.map
是可行的方法。
I am going to answer your question in a more general way, because it
appears to me you are asking about the difference between .forEach
and .map
in general.
Array.prototype
上的每个方法都是有目的的。 .map
的目的是在列表的所有项目上投影(或“映射”,因此得名)一个函数。因此,如果您想从值列表转到其他值列表,可以使用 .map
.
const sources = [1, 2, 3, 4, 5];
const results = sources.map(n => n + 1);
console.log(results); // logs [2, 3, 4, 5, 6]
要获得与 .forEach
相同的结果,您将拥有相同数量的变量,但您必须多执行两步编程:一步用于创建 results
数组,一步用于添加项目手动添加。
const sources = [1, 2, 3, 4, 5];
const results = [];
sources.forEach(n => {
results.push(n);
});
console.log(results);
通过直接比较,您可以很容易地看到使用 .forEach
会产生稍微多一些的代码,这些代码的声明性较低,但在风格上更具命令性。
如前所述,您也可以使用 .reduce
将一个函数映射到一个值并将其累加到结果列表中。事实上,利用.reduce
可以写出大量的操作。如果您好奇,请搜索 transducers
,这里有多个不同语言的库。
但回到使用 reduce
的示例:
const sources = [1, 2, 3, 4, 5];
const results = sources.reduce((acc, n) => acc.concat(n + 1), []);
console.log(results); // logs [2, 3, 4, 5, 6]
可在此处找到源内容:https://github.com/LinkedInLearning/javascript-essential-training-2832077/tree/main/08_17。有问题的代码就是这个块:
import backpackObjectArray from "./components/data.js";
const content = backpackObjectArray.map((backpack)=>{
let backpackArticle = document.createElement("article");
backpackArticle.classList.add("backpack");
// Set article ID to the backpack.id property
backpackArticle.setAttribute("id", backpack.id);
backpackArticle.innerHTML=`
<figure class="backpack__image">
<img src=${backpack.image} alt="" />
</figure>
<h1 class="backpack__name">${backpack.name}</h1>
<ul class="backpack__features">
<li class="packprop backpack__volume">Volume:<span> ${
backpack.volume
}l</span></li>
<li class="packprop backpack__color">Color:<span> ${
backpack.color
}</span></li>
<li class="backpack__age">Age:<span> ${backpack.backpackAge()} days old</span></li>
<li class="packprop backpack__pockets">Number of pockets:<span> ${
backpack.pocketNum
}</span></li>
<li class="packprop backpack__strap">Left strap length:<span> ${
backpack.strapLength.left
} inches</span></li>
<li class="packprop backpack__strap">Right strap length:<span> ${
backpack.strapLength.right
} inches</span></li>
<li class="feature backpack__lid">Lid status:<span> ${
backpack.lidOpen ? "open" : "closed"
}</span></li>
</ul>
`;
return backpackArticle;
})
const main = document.querySelector(".maincontent");
content.forEach((backpack)=>{
main.append(backpack);
}
)
本质上,是不是只用forEach循环就可以输出和我们使用map()数组方法一样的结果,即为每个对象输出一篇HTML篇文章?
*Pseudo-code* Array.prototype.map(function(ea){return backpackArticle})
将简单地创建一个新数组并在每次迭代中包含您 return 的任何内容。
您可以通过其他方式实现相同的目的,但是,如前所述,需要更多代码。实际上,本例中的 'significance' 只是用更少的代码实现了预期的结果。
我认为在您的示例中,它是显式创建一个新数组,然后使用 forEach 将每个 backpackArticle
显式附加到 <main>
。您可以跳过使用 map 创建新数组。
如果愿意,您绝对可以使用 forEach 循环,只是代码会稍有不同。如果您喜欢新代码的外观,则无需使用地图。
import backpackObjectArray from "./components/data.js";
const main = document.querySelector(".maincontent");
backpackObjectArray.forEach((backpack) => {
let backpackArticle = document.createElement("article");
backpackArticle.classList.add("backpack");
// Set article ID to the backpack.id property
backpackArticle.setAttribute("id", backpack.id);
backpackArticle.innerHTML = `
<figure class="backpack__image">
<img src=${backpack.image} alt="" />
</figure>
<h1 class="backpack__name">${backpack.name}</h1>
<ul class="backpack__features">
<li class="packprop backpack__volume">Volume:<span> ${
backpack.volume
}l</span></li>
<li class="packprop backpack__color">Color:<span> ${
backpack.color
}</span></li>
<li class="backpack__age">Age:<span> ${backpack.backpackAge()} days old</span></li>
<li class="packprop backpack__pockets">Number of pockets:<span> ${
backpack.pocketNum
}</span></li>
<li class="packprop backpack__strap">Left strap length:<span> ${
backpack.strapLength.left
} inches</span></li>
<li class="packprop backpack__strap">Right strap length:<span> ${
backpack.strapLength.right
} inches</span></li>
<li class="feature backpack__lid">Lid status:<span> ${
backpack.lidOpen ? "open" : "closed"
}</span></li>
</ul>
`;
main.append(backpackArticle);
});
编辑
抱歉,我似乎没有足够仔细地阅读您的问题。在您的情况下,是的,您可以将 .map
与 .forEach
互换并直接附加创建的元素而不将它们存储在中间数组中。
但是,我将保留其余部分,也许有人觉得它有用。
作为一个比较笼统的回答,“是的,您可以使用 .forEach
并获得相同的结果”。你也可以用 .reduce
来完成。但是,如果您想从源列表中获得结果列表(如您的示例所示),.map
是可行的方法。
I am going to answer your question in a more general way, because it appears to me you are asking about the difference between
.forEach
and.map
in general.
Array.prototype
上的每个方法都是有目的的。 .map
的目的是在列表的所有项目上投影(或“映射”,因此得名)一个函数。因此,如果您想从值列表转到其他值列表,可以使用 .map
.
const sources = [1, 2, 3, 4, 5];
const results = sources.map(n => n + 1);
console.log(results); // logs [2, 3, 4, 5, 6]
要获得与 .forEach
相同的结果,您将拥有相同数量的变量,但您必须多执行两步编程:一步用于创建 results
数组,一步用于添加项目手动添加。
const sources = [1, 2, 3, 4, 5];
const results = [];
sources.forEach(n => {
results.push(n);
});
console.log(results);
通过直接比较,您可以很容易地看到使用 .forEach
会产生稍微多一些的代码,这些代码的声明性较低,但在风格上更具命令性。
如前所述,您也可以使用 .reduce
将一个函数映射到一个值并将其累加到结果列表中。事实上,利用.reduce
可以写出大量的操作。如果您好奇,请搜索 transducers
,这里有多个不同语言的库。
但回到使用 reduce
的示例:
const sources = [1, 2, 3, 4, 5];
const results = sources.reduce((acc, n) => acc.concat(n + 1), []);
console.log(results); // logs [2, 3, 4, 5, 6]