繁体   English   中英

合并和分组两个Javascript对象数组和分组

[英]Merge & Group Two Javascript array of objects and Group

我有两个对象数组。 一个数组包含项目列表,另一个数组包含类别列表。 我想基于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/

谢谢您的帮助

以下是窍门:

 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()创建一个新的.concat()数组,该数组包含原始categories项目以及一个“空”类别。 然后,我对该数组进行.map()返回具有所需输出结构的类别对象,每个类别对象都有一个items数组,该数组由.filter()生成原始items数组产生。

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

您可以使用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' } ] }
 ]
*/

假设变量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 });
}, []);

暂无
暂无

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

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