javascript - 在这里正确使用函数式编程 : how do I use . map() 有效吗?

标签 javascript functional-programming ecmascript-6

我有两个数组: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".

但我想通过函数式编程来实现这一点,使用 ma​​p() 函数,并尝试使代码尽可能简短和高效。像这样的事情:

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/

相关文章:

javascript - 为什么我在 React 应用程序中失去了登录信息?

javascript - React,纯函数警告?

javascript - angular.identity() 有什么用例的好例子吗?

haskell - 函数式编程是否表现出控制流?

javascript - 使用 import 从 ES6 中的 cwd() 读取

Javascript、Jquery 通过将用户输入添加到自定义 url 来打开新选项卡

javascript - 比较同一数组的当前版本和先前版本以了解 JavaScript 中值的变化

javascript - 获取ES6类实例的类名

typescript - 如何修复 "property destructuring pattern expected"错误?

javascript - 当我按下获取路由按钮时,我希望我的 javascript 变量存储在数据库中