合并与第二组Javascript对象数组和组

时间:2016-07-28 04:25:39

标签: javascript arrays lodash

我有两个对象数组。一个数组包含项列表,另一个数组包含类别列表。我想基于categoryIds创建一个新数组。我尝试使用lodash。但是,无法得到正确的解决方案。

我可以使用循环来完成此操作。但是,我正在寻找更清洁的方法。

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/

感谢您的帮助

3 个答案:

答案 0 :(得分: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项和一个&#34;空的&#34;类别。然后我.map()该数组返回具有所需输出结构的类别对象,每个对象都有items数组,由.filter()原始items数组生成。< / p>

(请注意,items中的output数组包含对原始items输入中相同对象的引用,不是副本。如果您需要副本,可以在.map()之后添加另一个.filter()。)

答案 1 :(得分: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' } ] }
 ]
*/

答案 2 :(得分: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 });
}, []);