代码回顾:用Javascript简洁地对对象数组进行深度过滤



我已经尝试了一段时间来过滤对象数组,但我似乎无法真正掌握它。虽然我通常最终会有工作代码,但对我来说,它看起来不像是优雅的代码。所以,我非常感谢代码审查和一些提示!

示例:我目前正在为一家网店做这个示例,在那里我需要根据id从一组对象中检索产品详细信息。

这是我的助手功能:

function getItemDetails(id) {
var getCategory = shelf.filter(obj => obj.articleList.some(cat => cat.id === id));
var getArticleList = getCategory[0].articleList;
var getItem = getArticleList.filter(item => item.id == id);
return getItem 
}

步骤:在第一步中,我尝试过滤shelf数组,但它会返回相应项的整个数组articleList

所以,我用同样的标准再次过滤了结果,它有效,但对我来说它看起来非常多余。

这是一个数据示例:

const shelf = [{
"categoryPrice": "2",
"categoryTitle": "Flyer",
"articleList": [{
"id": "1",
"articleTitle": "Green",
}, {
"id": "2",
"articleTitle": "Blue",
}],
}, {
"categoryPrice": "3",
"categoryTitle": "Post card",
"articleList": [{
"id": "3",
"articleTitle": "Purple"
}, {
"id": "4",
"articleTitle": "Yellow",
}]
}]

我在这里检查了各种问题,包括:

  • 对象数组中深层对象中的Vue/Javascript过滤器
  • javascript数组中的深度过滤对象

但在我看来,它们都没有提供更简单、更简洁的解决方案。我错过了什么?

谢谢你的帮助!

这可能更适合代码审查,但如果问题只是"如何使其更简洁",我建议如下:

const shelf = [{
"categoryPrice": "2",
"categoryTitle": "Flyer",
"articleList": [{
"id": "1",
"articleTitle": "Green",
}, {
"id": "2",
"articleTitle": "Blue",
}],
}, {
"categoryPrice": "3",
"categoryTitle": "Post card",
"articleList": [{
"id": "3",
"articleTitle": "Purple"
}, {
"id": "4",
"articleTitle": "Yellow",
}]
}]
const findItem = function(shelves, id) {
return shelves.flatMap((shelf) => shelf.articleList).find((article) => article.id == id) || null;
}
console.log(findItem(shelf, 1));
console.log(findItem(shelf, 3));

上面的例子连接了所有的文章列表,然后用提供的ID在该数组中搜索文章。

性能方面?不是最好的,但你要求一些简洁的东西,这与给定的数据结构所希望的一样简洁。

此代码为O(1(,这意味着每个article.id的查找是恒定的。然而,它将使用更多的内存。为了节省内存,我使用了WeakMap,只要你使用相同的shelf变量,它就不会重新计算它。但一旦你替换了它,它也会从缓存中消失。

const shelf = [{
"categoryPrice": "2",
"categoryTitle": "Flyer",
"articleList": [{
"id": "1",
"articleTitle": "Green",
}, {
"id": "2",
"articleTitle": "Blue",
}, {
"id": "3",  //  Added
"articleTitle": "Violet",
}],
}, {
"categoryPrice": "3",
"categoryTitle": "Post card",
"articleList": [{
"id": "3",
"articleTitle": "Purple"
}, {
"id": "4",
"articleTitle": "Yellow",
}],
}];
const findItems = function(shelves, id) {
if (!findItems._map) {
// Create computation cache holder
// Weak map will make sure, that if the object is disposed, it can be garbage collected, with it will be gone its cache too! (That is awsome!)
findItems._map = new WeakMap();
}
if (!findItems._map.has(shelves)) {
// For every shelves object, we will create a new Map containing all mapped values.
const map = new Map();
findItems._map.set(shelves, map);
shelves.forEach(shelf => {
shelf.articleList.forEach(article => {
if (!map.has(article.id)) {
// If list is not yet created create it with the article
return map.set(article.id, [ article ]);
}

// If it exists, add to it
map.get(article.id).push(article);
});
});
}
return findItems._map.get(shelves).get(id);
}
console.log(findItems(shelf, "1"));
console.log(findItems(shelf, "3"));

您可以跳过两次循环。一次用于外部数组,一次用于articleList数组

const findItem = (id) =>
shelf.reduce((acc, current) => {
const found = current.articleList.find((x) => x.id === id);
if (found) return [...acc, found];
return acc;
}, []);

最新更新