【发布时间】:2017-01-05 15:59:18
【问题描述】:
我有两个数组:hobbieList 和 hobbieTypes。我想根据 hobbieTypes 数组中的索引值来分隔 hobbieList 中的元素。像这样的:
hobbieList = ["Rock", "Pop", "Surf", "Blues", "Soccer"];
hobbieTypes= ["music", "music", "sport", "music", "sport"];
...所以使用命令式编程和使用 fors 的典型方法是:
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:
我最终出于性能目的使用了命令式编程,但感谢大家为我在函数式编程中使用的不同方法。我的最终解决方案只是一个简单的 foo 循环:
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;
}
}
【问题讨论】:
-
为什么不使用过滤器?我认为它比地图更合适
-
除非您真正的意思是“有效地”,否则不要使用“有效地”这个词。
-
您的最后一句话:“我的最终解决方案只是一个简单的 foo 循环” – 这个解决方案很糟糕,因为数据值被硬编码到循环中。如果添加了其他类型的爱好,则必须调整代码。
标签: javascript functional-programming ecmascript-6