我有两个数组:hobbieList 和 hobbieTypes。我想根据 hobbieTypes 数组中索引的值来分隔 hobbieList 中的元素。像这样的事情:
hobbieList = ["Rock", "Pop", "Surf", "Blues", "Soccer"];
hobbieTypes= ["music", "music", "sport", "music", "sport"];
...因此使用命令式编程和使用 for 的典型方法是:
let musicHobbies = [];
for(let i=0;i<hobbieList.length;i++){
if(hobbieTypes[i] === "music"){
musicHobbies.push(hobbieList[i]);
}
}
// Now "musicHobbies" has only the hobbies which type is "music".
但我想通过函数式编程来实现这一点,使用 map() 函数,并尝试使代码尽可能简短和高效。像这样的事情:
let musicHobbies =
hobbieList.map( (elem, ind) => (hobbieTypes[ind] === "music") ? elem : null;
我认为它看起来不错,但有一个问题:空位置没有被删除,因此数组在不满足条件的情况下显示“空”。
<小时/>我可以进入的第二个方法是这样的,它工作得很好,但我不知道这是否是以函数方式编码的正确方法:
let musicHobbies = [];
rawHobbies.map( (elem, ind) => (hobbiesTypes[ind] === "music") ? musicHobbies.push(elem) : elem);
第二个解决方案设计得好吗?或者我应该改变什么?另外,我应该使用 map() 函数返回的数组(如情况 1),还是直接在外部数组中获取结果(如情况 2)是否可以?
感谢您的帮助!
编辑:
另一种方法怎么样?
rawHobbies.map( (elem, ind) => {
switch(hobbiesTypes[ind]){
case "music": this.hobbies.music.push(elem); break;
case "plan": this.hobbies.plans.push(elem); break;
case "hobbie": this.hobbies.hobbies.push(elem); break;
}
});
我想我用 forEach 会做得更好。你认为我应该使用这个,将它与 forEach 一起使用,或者做类似的事情......?
this.hobbies.music = rawHobbies.filter( (x,i) => hobbieTypes[i] == "music");
this.hobbies.plans = rawHobbies.filter( (x,i) => hobbieTypes[i] == "plan");
this.hobbies.hobbies = rawHobbies.filter( (x,i) => hobbieTypes[i] == "hobbie");
我不太确定这些选项中哪一个最有效。意见?
编辑2:
为了性能目的,我最终使用了命令式编程,但是感谢大家为我提供了可以在函数式编程中使用的不同方法。我的最终解决方案只是一个简单的四循环:
for(let i=0;i<rawHobbies.length;i++){
switch(hobbiesTypes[i]){
case "music": this.hobbies.music.push(rawHobbies[i]); break;
case "plan": this.hobbies.plans.push(rawHobbies[i]); break;
case "hobbie": this.hobbies.hobbies.push(rawHobbies[i]); break;
}
}
最佳答案
编辑后,您似乎想要更像 groupBy 的东西。
您可以使用.reduce()
来实现这一点。这应该适合你:
const hobbieList = ["Rock", "Pop", "Surf", "Blues", "Soccer"];
const hobbieTypes= ["music", "music", "sport", "music", "sport"];
var groupedHobbies = hobbieTypes.reduce( (acc, item, index) => {
acc[item] = [...(acc[item] || []), hobbieList[index]];
return acc;
}, {});
console.log(groupedHobbies);
通常,您希望副作用尽可能少,并且不要在 map 函数上同时执行很多操作(应该将每个元素映射/转换/转换为新元素,而不更改原始元素)。通过使用小函数,您可以稍后将它们组合起来(如果您继续遵循函数方法,您可能会阅读更多相关内容)
我建议您使用 .filter()
方法而不是 .map()
。
类似的事情:
hobbieList.filter((elem, ind) => hobbieTypes[ind] === "music")
这将返回一个数组,例如:
[
"Rock",
"Pop",
"Blues"
]
关于javascript - 在这里正确使用函数式编程 : how do I use . map() 有效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41489405/