javascript - 在 javascript 中使用 map 和 reduce 来过滤数组中的对象

标签 javascript filter mapping reduce

有一个freecodecamp的问题,详情如下:

要求:
创建一个查找对象数组(第一个参数)并返回具有匹配名称和值对的所有对象的数组(第二个参数)的函数。

例如,如果第一个参数是 [{ first: "Romeo", last: "Montague"}, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet"}],并且第二个参数是 { last: "Capulet"},那么您必须返回数组中的第三个对象(第一个参数),因为它包含作为第二个参数传递的名称及其值。

预期结果:

whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" }) should return [{ first: "Tybalt", last: "Capulet" }].

whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 }) should return [{ "apple": 1, "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }].

whatIsInAName([{ "apple": 1, "bat": 2 }, { "apple": 1 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "cookie": 2 }) should return [{ "apple": 1, "bat": 2, "cookie": 2 }].

whatIsInAName([{ "apple": 1, "bat": 2 }, { "apple": 1 }, { "apple": 1, "bat": 2, "cookie": 2 }, { "bat":2 }], { "apple": 1, "bat": 2 }) should return [{ "apple": 1, "bat": 2 }, { "apple": 1, "bat": 2, "cookie":2 }].

根据网站,有这样的解决方案:

function whatIsInAName(collection, source) {
  var srcKeys = Object.keys(source);

  // filter the collection
  return collection.filter(function (obj) {
    return srcKeys
      .map(function(key) {
        return obj.hasOwnProperty(key) && obj[key] === source[key];
      })
      .reduce(function(a, b) {
        return a && b;
      });
  });
}

// test here
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });

在这个解决方案中,有一件事我不是很理解,那就是map函数的返回值。

之前,在我的预期中,map 函数将循环遍历所有键值对以检查它是否匹配,并返回具有 bool 值的数组,即 [{true, false}, {false, false }] 等,并将 bool 值传递给 reduce 函数。

但是,当我使用以下脚本测试 map 功能时:

var source = { last: "Capulet" };
var collection = [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }];
var srcKeys = Object.keys({ last: "Capulet" });

collection.filter(function(obj){
  return srcKeys.map(function(key){
    return obj.hasOwnProperty(key) && obj[key] === source[key];
  })
})

返回是这样的

(3) [{…}, {…}, {…}]
 0: {first: "Romeo", last: "Montague"}
 1: {first: "Mercutio", last: null}
 2: {first: "Tybalt", last: "Capulet"}
 length: 3
  __proto__: Array(0)

在这种情况下,我有两个问题:

  1. 在 map 函数中,它创建一个新数组,其中包含对调用数组中的每个元素调用提供的函数的结果。在这种情况下,既然我们只想返回符合条件的元素,为什么不返回 bool 值或者只返回匹配值的元素,而是返回所有值呢? 还是我对映射函数的理解有误?

  2. 在map函数之后的reduce函数中,如何获取映射的 bool 值到一个单一的 bool 值,表示是否所有srcKey都通过了上面检查的条件?例如,在这种情况下,reduce 函数是否只是简单地获取 map 的返回值并进一步计算?

非常感谢您的提前帮助!

最佳答案

map 部分将 source 的所有键值对映射到一个 bool 值数组,指示该值是否在 obj 中:

 var obj = { a: 1, c: 3 };
 var source = { a: 1, b: 2, c: 3 };

 var mapped = Object.keys(source).map(key => obj[key] === source[key]);

 console.log(mapped); // [true, false, true]

现在数组不能作为返回值直接过滤,因为数组永远是真值,不管里面是什么。现在,reducer 将该数组转换为一个 bool 值,如下所示:

 [true, false, true].reduce((a, b) => a && b) // false

等同于:

 true && false && true // false

所以如果所有键值都存在,最后它返回 true。


PS:停止这门类(class),建议的代码很糟糕。

关于javascript - 在 javascript 中使用 map 和 reduce 来过滤数组中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52466938/

相关文章:

php - PHP安全性问题-SQL注入(inject),过滤和 session 安全性

json - 带 jq 的日期/数字过滤器

java - 与连接表中的类型单向关联

Java - 打印映射到从文件读取的键的值

spring-mvc - spring mvc Controller - 缺少名为 'xyz' 的 cookie

JavaScript:获取下拉列表的值

javascript - 单击 PayPal 购买按钮时如何显示 Window.alert

javascript - 设计程序以避免大型 if-else block

javascript - 在用户输入文本后保留图标

javascript - jquery 过滤来自 json 的数据类似于 Excel 数据透视表