在javascript中使用map和reduce过滤数组中的对象
freecodecamp有一个问题,详情如下: 要求:在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”},那么必须从数组返回第三个对象(第一个参数),因为它包含名称及其值,这是作为第二个参数
生成一个函数,用于查看对象数组(第一个参数),并返回具有匹配名称和值对(第二个参数)的所有对象的数组 例如,如果第一个参数是[{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
不是必需的
您可以使用函数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类似,但结果是它返回整个字符串。我能知道为什么吗?