为每个对象创建唯一的ID

问题描述 投票:0回答:4

Overview:有一个

product group
对象数组,每个产品组都有
items
数组。具有唯一 ID 的产品组对象,但项目数组未分配任何唯一 ID。请在下方找到 JSON 对象。

const productList = [{
  productGroup : 'PG1',
  index: 1,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}, {
  productGroup : 'PG2',
  index: 2,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}];

需求:根据产品组为

items
数组的每个项目对象分配一些唯一的ID。

我到目前为止尝试过:工作解决方案:产品组的连接索引与每个列表项的索引

const productList = [{
  productGroup : 'PG1',
  index: 1,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}, {
  productGroup : 'PG2',
  index: 2,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}];

const itemList = productList.map(obj => {
    obj.items.map((itemObj, index) => {
    itemObj.productGroup = obj.productGroup;
    itemObj.pgIndex = obj.index;
    itemObj.itemIndex = obj.index + '' + index;
  });
  return obj.items;
});

var mergedListItems = itemList.reduce((arr, arrNext) => arr.concat(arrNext));

console.log('mergedListItems', mergedListItems);

这个方法好吗?如果不是,那么最好的方法是什么?

javascript arrays json ecmascript-6 javascript-objects
4个回答
1
投票

您可能

.reduce
立即进入输出数组,而不是多次迭代项目:

const productList = [{
  productGroup : 'PG1',
  index: 1,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}, {
  productGroup : 'PG2',
  index: 2,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}];

const mergedListItems = productList.reduce((a, { productGroup, index, items }) => {
  items.forEach((itemObj, itemIndex) => {
    a.push({
      ...itemObj,
      productGroup,
      pgIndex: index,
      itemIndex: `${index}${itemIndex}`
    });
  });
  return a;
}, []);
console.log(mergedListItems);

另请注意,您的

可能存在问题
itemObj.itemIndex = obj.index + '' + index;

logic - 如果

index
大于 10 怎么办?然后,您可能会看到带有
itemIndex
的项目,例如
111
。这是什么意思,是说原始对象的索引是 11,还是项目索引是 11?如果可能,考虑在它们之间加上下划线或一些分隔符,例如

itemObj.itemIndex = obj.index + '_' + index;

或者,像我的代码一样使用模板字面量

itemIndex: `${index}_${itemIndex}`

1
投票

在你的代码中你使用

itemObj.itemIndex = obj.index + '' + index;

对于像

obj.index=12 index=3
obj.index=1 index=23
这样的案例来说,这可能不是唯一的。但是,如果您将
''
更改为
'-'
,它将是独一无二的。

尝试向每个项目对象添加字段“id”,如下所示

id= productGroup.index + '-' + i
(其中 i 是数组中的项目索引)

productList.forEach(pr=>pr.items.forEach((x,i)=> x.id = pr.index+'-'+i ));

const productList = [{
  productGroup : 'PG1',
  index: 1,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}, {
  productGroup : 'PG2',
  index: 2,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}];

productList.forEach(pr=>pr.items.forEach((x,i)=> x.id = pr.index+'-'+i ));

console.log(productList);

您还可以创建独立于 productGroup.index 的 uniqe id

let i=0;
productList.forEach(pr=>pr.items.forEach(x=> x.id = i++ ));

const productList = [{
  productGroup : 'PG1',
  index: 1,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}, {
  productGroup : 'PG2',
  index: 2,
  items: [{
    item1: 'item1 value',
    item2: 'item2 value'
  },{
    item1: 'item1 value',
    item2: 'item2 value'
  }]
}];

let i=0;
productList.forEach(pr=>pr.items.forEach(x=> x.id = i++ ));

console.log(productList);


0
投票

这里有一种使用 reduce() 和实验性 flatMap() 的方法。我也将产品名称附加到新的

identifier

const productList = [{
  productGroup : 'PG1',
  index: 1,
  items: [
    {item1: 'item1 value', item2: 'item2 value'},
    {item1: 'item1 value', item2: 'item2 value'},
    {item1: 'item1 value', item2: 'item2 value'}
  ]
},
{
  productGroup : 'PG2',
  index: 2,
  items: [
    {item1: 'item1 value', item2: 'item2 value'},
    {item1: 'item1 value', item2: 'item2 value'}
  ]
}];

let newList = productList.reduce((res, curr) =>
{
    let objs = curr.items.flatMap((x, idx) => Object.assign({
        productGroup: curr.productGroup,
        pgIndex: curr.index,
        itemIndex: [curr.productGroup, curr.index, idx].join("_")
    }, x));
    return res.concat(objs);
}, []);

console.log(newList);


0
投票

我在下面编写的代码将为您完成工作,并且是一个足够简单的可视化解决方案。 该解决方案需要使用嵌套 for 循环,因为我们也在遍历内部项数组。我在下面的代码中添加了一些注释来解释发生了什么。

      const productList = [{
      productGroup : 'PG1',
      index: 1,
      items: [{
        item1: 'item1 value',
        item2: 'item2 value'
      },{
        item1: 'item1 value',
        item2: 'item2 value'
      },{
        item1: 'item1 value',
        item2: 'item2 value'
      }]
    }, {
      productGroup : 'PG2',
      index: 2,
      items: [{
        item1: 'item1 value',
        item2: 'item2 value'
      },{
        item1: 'item1 value',
        item2: 'item2 value'
      }]
    }];

    var count;
    for(var char in productList){
        count = 1; // Will reset to 1 when we go to a new product group
        for(var i = 0; i < productList[char].items.length; i++){
            // Adding in the unique key to the items.
            productList[char].items[i].uniqueKey = productList[char].productGroup + "_" + count;
            count++; 
        }   
    }

希望这对您有所帮助:P 如果您有任何问题,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.