打字稿减少对象数组和增量属性

Typescript reduce object array and increment attribute

有一个项目数组如下

const items = [ { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 456, quantity: 1, description: "TESTNEW" }, ];

需要根据 itemId 减少此集合 属性 并根据相同的 itemId 增加数量。 预期输出为

[ { itemId: 123, quantity: 3, description: "TEST" }, { itemId: 456, quantity: 1, description: "TESTNEW" }, ];

如何在打字稿中使用 Array.reduce 来更新属性并且 select 仅使用唯一的 itemId 分享使用的打字稿代码。

    [![export interface MiniBagItem {
  name?: string;
  sku?: string;
  quantity?: number;
}
const item1: MiniBagItem = { name: "test", sku: "123", quantity: 1 };
const item2: MiniBagItem = { name: "test", sku: "123", quantity: 1 };
const item3: MiniBagItem = { name: "testNew", sku: "456", quantity: 1 };
const miniBagItems: MiniBagItem\[\] = \[\];
miniBagItems.push(item1, item2, item3);
//start reduce
let seenMap = new Map();
miniBagItems.reduce<MiniBagItem>((acc: MiniBagItem\[\], obj, index) => {
  let seen = seenMap.get(obj.sku);
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  seen !== undefined
    ? acc\[seen\].quantity++
    : (seenMap.set(obj.sku, index), acc.push(obj));
  acc.push(obj);
  return acc;
}, \[\]);

//console.log(newItems);
export {};

尝试按对象的属性之一进行过滤:

const items = [
  {
    itemId: 123,
    quantity: 1,
    description: 'TEST'
  },
  {
    itemId: 123,
    quantity: 1,
    description: 'TEST'
  },
  {
    itemId: 123,
    quantity: 1,
    description: 'TEST'
  },
  {
    itemId: 456,
    quantity: 1,
    description: 'TESTNEW'
  }
];

const res = items.filter((v, i, a) => a.findIndex((t) => t.itemId === v.itemId) === i);
console.log(res);

由于您的对象没有那么复杂,您可以使用 JSON.stringify()JSON.parse()

的简单方法 deep-equals

例子

const items = [
  { itemId: 123, quantity: 1, description: "TEST", },
  { itemId: 123, quantity: 1, description: "TEST", },
  { itemId: 123, quantity: 1, description: "TEST", },
  { itemId: 456, quantity: 1, description: "TESTNEW", },
];

const flatItems = items.map(item => JSON.stringify(item));
let reduced = [];

flatItems.forEach((flatItem) => {
  if (!reduced.includes(flatItem)) {
    reduced.push(flatItem);
  }
})

reduced = reduced.map(flatReduced => JSON.parse(flatReduced));

//this code is just for priting the result in HTML
document.querySelector('pre code').textContent = JSON.stringify(reduced, null, 2); hljs.highlightElement(document.querySelector('pre code'))
<link rel="stylesheet"
      href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/ocean.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.2.0/highlight.min.js"></script>

<pre><code class="language-json hljs"></code></pre>

您可以使用 array#reduce 遍历 items 数组中的每个对象,并使用累加器 (acc) 来保存新的对象数组 quantity 属性设置。

const items = [ { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 123, quantity: 1, description: "TEST" }, { itemId: 456, quantity: 1, description: "TESTNEW" }, ];

let seenMap = new Map();
const newItems = items.reduce((acc, obj, index) => {
  let seen = seenMap.get(obj.itemId);
  seen !== undefined ? acc[seen].quantity++ : (seenMap.set(obj.itemId, index), acc.push(obj));
  return acc;
}, []);

console.log(newItems);

注意:我在这里使用 Map() 而不是 seenMap 变量的数组来保持时间复杂度 O(N).

您需要使用的打字稿:

export interface MiniBagItem {
  name?: string;
  sku?: string;
  quantity?: number;
}
const item1: MiniBagItem = { name: "test", sku: "123", quantity: 1 };
const item2: MiniBagItem = { name: "test", sku: "123", quantity: 1 };
const item3: MiniBagItem = { name: "testNew", sku: "456", quantity: 1 };
const miniBagItems: MiniBagItem[] = [];
miniBagItems.push(item1, item2, item3);

//start reduce
let seenMap: Map<string, number> = new Map();
miniBagItems.reduce<MiniBagItem[]>((acc: MiniBagItem[], obj, index) => {
  let seen = seenMap.get(obj.sku);
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  seen !== undefined
    ? acc[seen].quantity++
    : (seenMap.set(obj.sku, index), acc.push(obj));

  acc.push(obj);
  return acc;
}, []);

//console.log(newItems);
export {};