打字稿减少对象数组和增量属性
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 {};
有一个项目数组如下
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 {};