簡體   English   中英

基於屬性合並兩個數組

[英]Merging two arrays based on Property

我有兩個數組:一個包含類別,第二個包含項目。

我想使用lodash將所有項目項合並到其適當的類別數組中。 但是,我確實有一個問題。 由於這可以通過雙foreach循環完成,因此有沒有理由使用lodash?

數組1(類別):

"categories": [
    {
        "id": 1,
        "name": "cat_1",
        "items": []
    },
    {
        "id": 11,
        "name": "cat_2",
        "items": []
    },
    {
        "id": 61,
        "name": "cat_3",
        "items": []
    }
]

數組2(包含項):

[ 
    { 
        id: 15,
        name: 'some_item',
        category_id: 1,
        category_name: 'cat_1',
    },
    { 
        id: 112,
        name: 'some_item',
        category_id: 11,
        category_name: 'cat_2',
    },
    { 
        id: 235,
        name: 'some_item',
        category_id: 11,
        category_name: 'cat_2',
    },

]

所需的對象將如下所示:

"categories": 
    [
        {
            "id": 1,
            "name": "cat_1",
            "items": [
                { 
                    id: 15,
                    name: 'some_item',
                    category_id: 1,
                    category_name: 'cat_1',
                }
            ]
        },
        {
            "id": 11,
            "name": "cat_2",
            "items": [
                { 
                    id: 112,
                    name: 'some_item',
                    category_id: 11,
                    category_name: 'cat_2',
                },
                { 
                    id: 235,
                    name: 'some_item',
                    category_id: 11,
                    category_name: 'cat_2',
                }
            ]
        },
        {
            "id": 61,
            "name": "cat_3",
            "items": []
        }
    ]

這是使用普通ES5的方法:

 const categories = [{id:1,name:"cat_1",items:[]},{id:11,name:"cat_2",items:[]},{id:61,name:"cat_3",items:[]}] const items = [{id:15,name:"some_item",category_id:1,category_name:"cat_1"},{id:112,name:"some_item",category_id:11,category_name:"cat_2"},{id:235,name:"some_item",category_id:11,category_name:"cat_2"}]; const result = categories.map(c => ({ ...c, items: items.filter(i => i.category_id === c.id) })); console.log(result); 

由於Java的歷史,它是一種非常特殊的語言。 它最初是一種非常不起眼的語言,幾乎沒有任何功能,盡管它已經發展了,但並非所有瀏覽器都支持所有功能。

這引起了像lodash,underscore,inmutable.js和jquery之類的庫的出現,從而填補了Javascript標准庫中的空白。

如您所見,現在JS具有非常方便的抽象,例如eachmapfindfilterreduce ,它們是跨語言的普遍理解的概念。 與使用for循環編寫低級的過程代碼相比,這使代碼更易於理解。

作為一個顏色說明,我開始使用ruby進行編程,它以擁有豐富的集合抽象標准庫而聞名。 結果,直到最近,我才注意到語言中的for循環在哪里,即使實現高層抽象是必要的。

我從未使用過lodash,但是您是對的,可以使用foreach循環輕松完成此操作。 甚至沒有兩個foreach循環,只有一個帶有'.find'或'.filter'的循環

(a)遍歷每個項目並使用array.find查找合適的類別,然后將項目輸入到類別中

(b)遍歷每個類別,並使用array.filter查找適當的項目,然后將這些項目輸入每個類別。

這是一種選擇:

(()=>{
  const categories = [{
      "id": 1,
      "name": "cat_1",
      "items": []
    },
    {
      "id": 11,
      "name": "cat_2",
      "items": []
    },
    {
      "id": 61,
      "name": "cat_3",
      "items": []
    }]

  const items = [{ 
      id: 15,
      name: 'some_item',
      category_id: 1,
      category_name: 'cat_1',
    },
    { 
      id: 112,
      name: 'some_item',
      category_id: 11,
      category_name: 'cat_2',
    },
    { 
      id: 235,
      name: 'some_item',
      category_id: 11,
      category_name: 'cat_2',
    }]

  categories.forEach((cat) => {
    cat.items = items.filter((item) => item.category_id === cat.id);
  })
})()

您可以使用lodash _.keyBy()按類別ID對項目進行分組,然后使用Array#map循環類別,並創建新的類別對象,其中項目取自itemsByCategory

 const categories = [{"id":1,"name":"cat_1","items":[]},{"id":11,"name":"cat_2","items":[]},{"id":61,"name":"cat_3","items":[]}]; const items = [{"id":15,"name":"some_item","category_id":1,"category_name":"cat_1"},{"id":112,"name":"some_item","category_id":11,"category_name":"cat_2"},{"id":235,"name":"some_item","category_id":11,"category_name":"cat_2"}]; const itemsByCategory = _.groupBy(items, 'category_id'); const categoriesWithItems = categories.map(({ id, name, items }) => ({ id, name, items: items.concat(itemsByCategory[id]) })); console.log(categoriesWithItems); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> 

如您所見,我使用的唯一lodash方法是_.keyBy() ,我們可以將其替換為Array#reduce

 const categories = [{"id":1,"name":"cat_1","items":[]},{"id":11,"name":"cat_2","items":[]},{"id":61,"name":"cat_3","items":[]}]; const items = [{"id":15,"name":"some_item","category_id":1,"category_name":"cat_1"},{"id":112,"name":"some_item","category_id":11,"category_name":"cat_2"},{"id":235,"name":"some_item","category_id":11,"category_name":"cat_2"}]; const itemsByCategory = items.reduce((r, item) => { r[item.category_id] = item; return r; }, {}); const categoriesWithItems = categories.map(({ id, name, items }) => ({ id, name, items: items.concat(itemsByCategory[id]) })); console.log(categoriesWithItems); 

因此,使用lodash主要是為了方便。 由於lodash是用JS編寫的,因此您可以使用JS創建lodash所做的任何事情(ES6使工作更輕松),並且可以節省一些捆綁包的大小。 但是,lodash確實可以節省大量手寫的,經過純測試的代碼,從而重新發明了輪子。 我建議使用lodash-es而不是lodash,因為es版本是模塊化的,因此您可以導入所需的內容。 這可以在易用性和捆束尺寸之間取得平衡。

您可以為類別選擇一個Map ,然后迭代項目以推送到相應的類別。

 var object = { categories: [{ id: 1, name: "cat_1", items: [] }, { id: 11, name: "cat_2", items: [] }, { id: 61, name: "cat_3", items: [] }] }, items = [{ id: 15, name: 'some_item', category_id: 1, category_name: 'cat_1', }, { id: 112, name: 'some_item', category_id: 11, category_name: 'cat_2', }, { id: 235, name: 'some_item', category_id: 11, category_name: 'cat_2', }], map = new Map(object.categories.map(category => [category.id, category.items])); items.forEach(item => map.get(item.category_id).push(item)); console.log(object); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM