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