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

在javascript中使用map和reduce过滤数组中的对象,javascript,filter,mapping,reduce,Javascript,Filter,Mapping,Reduce,freecodecamp有一个问题,详情如下: 要求: 生成一个函数,用于查看对象数组(第一个参数),并返回具有匹配名称和值对(第二个参数)的所有对象的数组 例如,如果第一个参数是[{first:“Romeo”,last:“Montague”},{first:“Mercutio”,last:null},{first:“Tybalt”,last:“Capulet”}],第二个参数是{last:“Capulet”},那么必须从数组返回第三个对象(第一个参数),因为它包含名称及其值,这是作为第二个参数

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函数将循环遍历所有键和值对以检查其是否匹配,并返回带有布尔值的数组,例如[{true,false},{false,false}]等,然后将布尔值传递给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)
在这种情况下,我有两个问题:

  • 在map函数中,它创建一个新数组,其中包含对调用数组中的每个元素调用所提供函数的结果。在本例中,由于我们只想返回与条件匹配的元素,为什么它不返回布尔值或仅返回具有匹配值的元素,而是返回所有值? 或者我对映射函数的理解有误吗

  • 在映射函数之后的reduce函数中,它如何获得映射到单个布尔值的布尔值,该布尔值指示是否所有srcKeys都通过上述检查的条件?例如,在这种情况下,reduce函数是否只是获取map的返回值并进一步计算


  • 非常感谢您的帮助

    正如我所说,函数
    map
    不是必需的

    您可以使用函数
    filter
    和函数
    every
    来过滤与键值对对象(第二个参数)匹配的对象

    let whatisiname=(arr,obj)=>arr.filter(o=>Object.keys(obj.every)(k=>obj[k]==o[k]);
    log(whatisiname([{“苹果”:1,“蝙蝠”:2},{“蝙蝠”:2},{“苹果”:1,“蝙蝠”:2,“饼干”:2}],{“苹果”:1,“蝙蝠”:2}));
    log(whatisiname([{“first”:“Romeo”,“last”:“Montague”},{“first”:“Mercutio”,“last”:null},{“first”:“Tybalt”,“last”:“Capulet”}),{“last”:“Capulet”});
    log(whatisiname([{apple:1,bat:2},{apple:1},{apple:1,bat:2,cookie:2}],{apple:1,cookie:2}));
    log(whatisiname([{“苹果”:1,“蝙蝠”:2},{“苹果”:1},{“苹果”:1,“蝙蝠”:2,“饼干”:2},{“苹果”:1,“蝙蝠”:2}])
    
    .as控制台包装{max height:100%!important;top:0;}
    映射部分将
    的所有键值对映射到一个布尔数组,该数组指示值是否在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将该数组转换为一个布尔值,如下所示:

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

     true && false && true // false
    
    因此,如果所有键值都存在,则在最后返回true



    PS:停止本课程,建议的代码很糟糕。

    提示:绝对不需要函数
    map
    。在示例1中,map函数的返回值是一个真/假值数组,取决于当前对象是否通过了每个测试。然后reduce函数将所有这些真/假值相加,生成true(是的,此元素通过了所有条件)或false(一个或多个失败)。.filter函数对最后一个布尔值进行操作。在测试中,您看到的是.filter操作的输出,而不是.mapping替换prev comment的最后一句话。在您的测试中,.filter中的函数返回一个真/假值数组,而不是将其逻辑转换为单个真/假值(这就是.reduce所做的)@James谢谢!请允许我澄清一下,这意味着在本例中,虽然map函数在控制台日志中没有返回带有布尔值的数组,但返回的结果中已经包含一个带有布尔值的隐式数组,并且可以进一步使用reduce?谢谢!实际上,这种方法效果更好,但只是想澄清一些我可能不理解的概念,因为我在这方面还是个初学者=)谢谢,它准确地回答了我的疑问=)PS:我也知道这一点,但似乎是一个好方法,至少可以理解事情是如何工作的,即使代码不是最佳实践,这就是为什么仍在阅读它(哈哈=),还有一个问题:因为我还期望映射的结果与映射的var类似,但结果是它返回整个字符串。我能知道为什么吗?