2016-07-28 60 views
0

我有兩個對象數組。一個數組包含項目列表,另一個數組包含類別列表。我想創建一個基於categoryIds的新數組。我嘗試使用lodash。但是,無法得到正確的解決方案。合併與第二組對象的Javascript數組和組

我可以使用循環來做到這一點。但是,我正在尋找更乾淨的方法。

var items = [ 
    { 
    id: '001', 
    name: 'item1', 
    description: 'description of item1', 
    categoryId: 'cat1' 
    }, 
    { 
    id: '002', 
    name: 'item2', 
    description: 'description of item2', 
    categoryId: 'cat2' 
    }, 
    { 
    id: '003', 
    name: 'item3', 
    description: 'description of item3', 
    categoryId: 'cat1' 
    }, 
    { 
    id: '004', 
    name: 'item4', 
    description: 'description of item4' 
    } 
]; 

var categories = [ 
    { 
    id: 'cat1', 
    name: 'Category1' 
    }, 
    { 
    id: 'cat2', 
    name: 'Category2' 
    } 
]; 

預計輸出

[ 
{ 
    categoryId: 'cat1', 
    name: 'Category1', 
    items: [ 
    { 
     id: '001', 
     name: 'item1', 
     description: 'description of item1', 
     categoryId: 'cat1' 
    }, 
    { 
     id: '003', 
     name: 'item3', 
     description: 'description of item3', 
     categoryId: 'cat1' 
    } 
    ] 
}, 
{ 
    categoryId: 'cat2', 
    name: 'Category2', 
    items: [ 
    { 
    id: '002', 
    name: 'item2', 
    description: 'description of item2', 
    categoryId: 'cat2' 
    } 
    ] 
}, 
{ 
    categoryId: '', 
    name: '', 
    items: [ 
    { 
    id: '004', 
    name: 'item4', 
    description: 'description of item4' 
    } 
    ] 
} 
] 

https://jsfiddle.net/sfpd3ppn/

感謝您的幫助

+0

* - 哪裏是你的企圖:「我可以用循環做到這一點。」?你的小提琴只包括輸入對象和所需的輸出。 – nnnnnn

+0

對不起。我已經更新了jsfiddle。請看一看。 https://jsfiddle.net/sfpd3ppn/1/ – jintoppy

回答

0

可以完成使用reduce期望的結果。我們將從原始categories陣列開始,並將其中的items陣列減少。

var items = [ 
    { id: '001', name: 'item1', description: 'description of item1', categoryId: 'cat1' }, 
    { id: '002', name: 'item2', description: 'description of item2', categoryId: 'cat2' }, 
    { id: '003', name: 'item3', description: 'description of item3', categoryId: 'cat1' }, 
    { id: '004', name: 'item4', description: 'description of item4' } 
]; 

var categories = [ 
    { id: 'cat1', name: 'Category1' }, 
    { id: 'cat2', name: 'Category2' } 
]; 


// Lets add the empty category at the beginning. This simplifies the logic. 
categories.push({ id: '', name: '' }); 

// This is a function that will return a function to be used as a filter later on 
function createFilter (category) { 
    return function (item) { 
    return item.id === category; 
    }; 
} 

var mergedSet = items.reduce(function (previous, current) { 
    // Get the category ID of the current item, if it doesn't exist set to empty string 
    var categoryId = current.categoryId || ''; 

    // Find the cateogry that matches the category ID 
    var category = previous.find(createFilter(categoryId)); 

    // If the items property doesn't exists (we don't have any items), create an empty array 
    if (!category.items) { category.items = []; } 

    // Add the item the category 
    category.items.push(current); 

    // Return the current value that will be used in the next iteration. 
    // Note, the initial value of previous will be the intial value of categories. 
    return previous; 

}, categories); 

console.log(mergedSet); 

/* Output 
[ 
    { id: 'cat1', 
    name: 'Category1', 
    items: 
    [ { id: '001', 
     name: 'item1', 
     description: 'description of item1', 
     categoryId: 'cat1' }, 
     { id: '003', 
     name: 'item3', 
     description: 'description of item3', 
     categoryId: 'cat1' } 
     ] 
    }, 
    { id: 'cat2', 
    name: 'Category2', 
    items: 
    [ { id: '002', 
     name: 'item2', 
     description: 'description of item2', 
     categoryId: 'cat2' 
     } 
     ] 
    }, 
    { id: '', 
    name: '', 
    items: 
     [ { id: '004', 
      name: 'item4', 
      description: 'description of item4' } ] } 
] 
*/ 
1

下面的伎倆:

var items = [{ id: '001', name: 'item1', description: 'description of item1', categoryId: 'cat1' }, { id: '002', name: 'item2', description: 'description of item2', categoryId: 'cat2' }, { id: '003', name: 'item3', description: 'description of item3', categoryId: 'cat1' }, { id: '004', name: 'item4', description: 'description of item4' } ]; 
 

 
var categories = [ { id: 'cat1', name: 'Category1' }, { id: 'cat2', name: 'Category2' } ]; 
 

 
var output = categories.concat([{id:'',name:''}]).map(function(v) { 
 
    return { 
 
    categoryId: v.id, 
 
    name: v.name, 
 
    items: items.filter(function(o) { 
 
     return o.categoryId === v.id || !o.categoryId && !v.id; 
 
    }) 
 
    }; 
 
}); 
 

 
console.log(output);

我用.concat()創建一個新的類別數組保存原始categories項目加上一個「空」類別開始。然後,我.map()該數組返回類別對象與您所需的輸出結構,其中每個具有items陣列由.filter()數組生成的原始items數組。

(注意:outputitems陣列包含對在原始items輸入相同的對象,不是他們的副本引用。如果你想拷貝你可以在.filter()後再添.map()。)

0

假設變量categoriesitems如你在上面定義的分配:

const keyedCategories = _(categories) 
    .concat({ id: '', name: '' }) 
    .keyBy('id') 
    .value(); 

const groupedItems = _.groupBy(items, (item) => _.get(item, 'categoryId', '')); 

const result = _.reduce(groupedItems, (acc, value, key) => { 
    const { id: categoryId, name } = keyedCategories[key]; 
    return _.concat(acc, { categoryId, name, items: value }); 
}, []);