简体   繁体   English

代码审查:Javascript 中简洁的对象的深度过滤器数组

[英]Code review: Deep filter array of objects concisely in Javascript

I've been trying to wrap my head around filtering arrays of objects for a while now, but I can't seem to really get a hang on it.一段时间以来,我一直在尝试过滤 arrays 对象,但我似乎无法真正掌握它。 Although I usually have working code in the end, it just doesn't look like elegant code to me.虽然最后我通常有工作代码,但对我来说它看起来并不像优雅的代码。 So, I'd appreciate a code review and some hints very much!所以,我非常感谢代码审查和一些提示!

Example: I'm currently working on this example for an online shop where I need to retrieve product details out of an array of objects based on an id.示例:我目前正在为一家在线商店开发此示例,我需要从基于 id 的对象数组中检索产品详细信息。

This is my helper function:这是我的助手 function:

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 
}

Steps: In a first step, I tried to filter the shelf array, but it would return the entire array articleList of the corresponding item.步骤:在第一步中,我尝试过滤shelf数组,但它会返回相应项目的整个数组articleList

So, I filtered the result again with the same criteria and it works , but it just looks awfully redundant to me.所以,我用相同的标准再次过滤了结果,它可以工作,但它对我来说看起来非常多余。

This is an example of the data:这是一个数据示例:

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",
    }]
}]

I checked various questions here, including:我在这里检查了各种问题,包括:

But none of them provide an easier, more concise solution, in my opinion.但在我看来,它们都没有提供更简单、更简洁的解决方案。 What am I missing?我错过了什么?

Thanks for your help!谢谢你的帮助!

This might be a better fit for codereview but if the question is just 'How to make this more concise' I would suggest something like following:这可能更适合codereview ,但如果问题只是“如何使它更简洁”,我会建议如下内容:

 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));

The above example concatenate all the list of articles and then searches that array for the article with the supplied ID.上面的示例连接所有文章列表,然后在该数组中搜索具有提供 ID 的文章。

Performance wise?性能明智? Not the best, but you asked for something concise and this is about as concise as one can hope for with the given data structure.不是最好的,但是您要求一些简洁的东西,这与给定数据结构所希望的一样简洁。

This code is O(1), which means that lookup per article.id is constant.此代码为 O(1),这意味着每个article.id的查找是恒定的。 It will however use more memory.然而,它将使用更多的 memory。 To conserve memory, I used WeakMap , as long as you use the same shelf variable, it will not recompute it.为了节省 memory,我使用WeakMap ,只要你使用相同的shelf变量,它就不会重新计算它。 But once you replace it, it will also perish from the cache.但是一旦你替换它,它也会从缓存中消失。

 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"));

You can get away with looping twice.你可以摆脱循环两次。 Once for the outer array and once for the articleList array一次用于外部数组,一次用于 articleList 数组

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM