JavaScript: 使用对象过滤对象数组
JavaScript: filter array of objects using an object
我正在尝试从 freecodecamp 进行以下挑战:https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/wherefore-art-thou 我对此有几个问题。
- 为什么我的尝试在我的本地控制台上有效,但在 freecodecamp 上无效?意思是,在所有测试中,4 个中有 3 个在我的控制台中是正确的,但其中 none 在 FCC 上。
- 为什么这个测试
whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 })
没有通过,而其他所有测试都通过了?
我的尝试与预期结果:
function whatIsInAName(collection, source) {
const arr = [];
// Only change code below this line
let finalObj = collection
.map(item => Object.entries(item))
.filter(el => String(el).includes(String(Object.values(source))))
.map(el => Object.fromEntries(el))
arr.push(finalObj);
console.log(arr);
// Only change code above this line
return arr;
}
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" }) // should return [{ first: "Tybalt", last: "Capulet" }]
whatIsInAName([{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }], { "apple": 1 }) // should return [{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 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 }]
whatIsInAName([{"a": 1, "b": 2, "c": 3}], {"a": 1, "b": 9999, "c": 3}) // should return []
- 使用
Object#entries
,从source
获取键值对列表
- 使用
Array#filter
, iterate over collection
. In every iteration, using Array#every
,检查上面sourceEntries
中的所有条目是否匹配当前对象
function whatIsInAName(collection, source) {
const sourceEntries = Object.entries(source);
return collection.filter(e =>
sourceEntries.every(([key, value]) => e[key] === value)
);
}
console.log(
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" })
);
console.log(
whatIsInAName([{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }], { "apple": 1 })
);
console.log(
whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 })
);
console.log(
whatIsInAName([{ "a": 1, "b": 2, "c": 3 }], { "a": 1, "b": 9999, "c": 3 })
);
为了分析您的代码,我们先添加日志:
function whatIsInAName(collection, source) {
const arr = [];
let finalObj = collection
.map(item => {
const entries = Object.entries(item);
console.log(1, entries);
return entries;
})
.filter(el => {
console.log(2, String(el), String(Object.values(source)));
return String(el).includes(String(Object.values(source)))
})
.map(el => {
const obj = Object.fromEntries(el);
console.log(3, obj);
return obj;
});
console.log(4, finalObj);
arr.push(finalObj);
console.log(5, arr);
return arr;
}
whatIsInAName([{ "apple": 1, "bat": 2 }], { "apple": 1, "bat": 2 });
总而言之,您的方法是迭代 collection
,将每个项目转换为条目列表。然后,通过检查项目的条目(字符串化)是否包含源(字符串化)的值来过滤这些条目。之后,将通过过滤的条目转换回对象,从而生成对象数组。将此数组添加到初始数组和 return 后者。
问题:
- 当
source
有多个 属性 时它停止工作,例如,您将检查“apple,1,bat,2”是否包含“1,2”。即使您在此处检查 source
条目,您仍然会假设属性的顺序。总之,将对象字符串化不是正确的方法,这就是为什么最好检查 source
中的每个键是否与其在给定项目中的值匹配。
- 第三个
Array#map
return 是一个数组,然后您将其添加 (finalObj
) 到另一个数组 arr
。
我正在尝试从 freecodecamp 进行以下挑战:https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/wherefore-art-thou 我对此有几个问题。
- 为什么我的尝试在我的本地控制台上有效,但在 freecodecamp 上无效?意思是,在所有测试中,4 个中有 3 个在我的控制台中是正确的,但其中 none 在 FCC 上。
- 为什么这个测试
whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 })
没有通过,而其他所有测试都通过了?
我的尝试与预期结果:
function whatIsInAName(collection, source) {
const arr = [];
// Only change code below this line
let finalObj = collection
.map(item => Object.entries(item))
.filter(el => String(el).includes(String(Object.values(source))))
.map(el => Object.fromEntries(el))
arr.push(finalObj);
console.log(arr);
// Only change code above this line
return arr;
}
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" }) // should return [{ first: "Tybalt", last: "Capulet" }]
whatIsInAName([{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }], { "apple": 1 }) // should return [{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 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 }]
whatIsInAName([{"a": 1, "b": 2, "c": 3}], {"a": 1, "b": 9999, "c": 3}) // should return []
- 使用
Object#entries
,从source
获取键值对列表
- 使用
Array#filter
, iterate overcollection
. In every iteration, usingArray#every
,检查上面sourceEntries
中的所有条目是否匹配当前对象
function whatIsInAName(collection, source) {
const sourceEntries = Object.entries(source);
return collection.filter(e =>
sourceEntries.every(([key, value]) => e[key] === value)
);
}
console.log(
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" })
);
console.log(
whatIsInAName([{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }], { "apple": 1 })
);
console.log(
whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 })
);
console.log(
whatIsInAName([{ "a": 1, "b": 2, "c": 3 }], { "a": 1, "b": 9999, "c": 3 })
);
为了分析您的代码,我们先添加日志:
function whatIsInAName(collection, source) {
const arr = [];
let finalObj = collection
.map(item => {
const entries = Object.entries(item);
console.log(1, entries);
return entries;
})
.filter(el => {
console.log(2, String(el), String(Object.values(source)));
return String(el).includes(String(Object.values(source)))
})
.map(el => {
const obj = Object.fromEntries(el);
console.log(3, obj);
return obj;
});
console.log(4, finalObj);
arr.push(finalObj);
console.log(5, arr);
return arr;
}
whatIsInAName([{ "apple": 1, "bat": 2 }], { "apple": 1, "bat": 2 });
总而言之,您的方法是迭代 collection
,将每个项目转换为条目列表。然后,通过检查项目的条目(字符串化)是否包含源(字符串化)的值来过滤这些条目。之后,将通过过滤的条目转换回对象,从而生成对象数组。将此数组添加到初始数组和 return 后者。
问题:
- 当
source
有多个 属性 时它停止工作,例如,您将检查“apple,1,bat,2”是否包含“1,2”。即使您在此处检查source
条目,您仍然会假设属性的顺序。总之,将对象字符串化不是正确的方法,这就是为什么最好检查source
中的每个键是否与其在给定项目中的值匹配。 - 第三个
Array#map
return 是一个数组,然后您将其添加 (finalObj
) 到另一个数组arr
。