javascript - 如何在 TypeScript 中进行投影?
问题描述
我想填充orders
type 的数组Order
。预期的结果是orders=[{id:1,qt:4},{id:2, qt:2},{id:3,qt:2}]
。如何在 TypeScript 中这样做?我是新手。
export class Product {
constructor(public id: number, public name: string, public price: number) {}
}
export interface Order {
id: number;
qt: number;
}
export const products: Product[] = [
new Product(1, 'Apple', 2.1),
new Product(2, 'Banana', 2.2),
new Product(3, 'Chocolate', 2.3),
new Product(4, 'Dessert', 2.4),
];
export const cart: Product[] = [
products[0],
products[0],
products[2],
products[1],
products[2],
products[0],
products[1],
products[0],
];
export const orders: Order[] = [];
编辑
对于那些想知道如何
orders=[{id:1,qt:4},{id:2, qt:2},{id:3,qt:2}]
获得的人。
在cart
:
- 苹果的数量 (
id:1
) 是qt:4
- 香蕉的数量 (
id:2
) 是qt:2
- 巧克力的数量 (
id:3
) 是qt:2
所以通过使用购物车,我必须获得orders=[{id:1,qt:4},{id:2, qt:2},{id:3,qt:2}]
. 应该很清楚。
解决方案
由于您正在寻找“类似 LINQ”的解决方案,因此您可能想要使用更高阶的函数,例如map
// filter
。reduce
严格来说,您的问题不能仅通过 LINQ 投影来解决。这些仅表示map
( Select
)、concatMap
/ flatMap
( SelectMany
) 和zip
( Zip
)。您的问题涉及计算id
整个数组中每个的出现次数。
几乎每个数据操作问题都可以通过更高阶的折叠来解决,即reduce
在 javascript 领域,Aggregate
在 C# 领域。这个也不例外。首先要做的是计算每个 的出现次数id
,并构建一个计数器对象。
cart.reduce((acc, { id }) => {
acc[id] = (acc[id] ?? 0) + 1;
return acc;
}, {} as Record<number, number>);
本质上,您从一个空对象开始折叠操作,然后添加每个对象id
及其出现次数。每次id
在数组中遇到an 时cart
,都会增加它在对象中的计数。如果id
累积对象中不存在 ,则无效合并 ( acc[id] ?? 0
) 使用0
并增加它。
这会给你——
{ '1': 4, '2': 2, '3': 2 }
现在,你需要把它变成——
[ { id: 1, qt: 4 }, { id: 2, qt: 2 }, { id: 3, qt: 2 } ]
为此,使用Object.entries
折叠结果来获得 -
> Object.entries({ '1': 4, '2': 2, '3': 2 })
[ [ '1', 4 ], [ '2', 2 ], [ '3', 2 ] ]
最后,一个简单map
的就是你所需要的——
Object.entries(...).map(([id, qt]) => ({ id: Number(id), qt }))
结合所有这些,你有 -
export const orders: Order[] = Object.entries(
cart.reduce((acc, { id }) => {
acc[id] = (acc[id] ?? 0) + 1;
return acc;
}, {} as Record<number, number>)
).map(([id, qt]) => ({ id: Number(id), qt }));
这里要注意的一件事Object.entries
是效率非常低,因为它构建了一个数组而不是迭代器。如果您想提高效率,请Object.entries
使用生成器函数滚动迭代器版本并使用它-
function* objEntries<T>(x: Record<string, T>): IterableIterator<[string, T]> {
for (const k in x) {
yield [k, x[k]];
}
}
推荐阅读
- scala - 如何在播放框架中以 Scala 形式使用 POST 方法?
- vhdl - 这个 VHDL 代码会造成分配冲突吗?
- angular7 - this.xxxx.emit 不是函数
- python - Airflow - 在 BranchPythonOperator 中访问 Xcom
- typescript - 函数的返回类型可以取决于输入参数的值吗?
- php - Symfony yml - 带@的密码
- matlab - 在 MATLAB 的 txtfile 中查找所有可见字符(并检查是否没有现有文件)
- reactjs - 如何在没有 {" "} 的情况下使用 ESLint、Prettier 和 Flow 结束标记在 VSCode 中格式化 React Project
- r - 如何在R中对向量进行分类以绘制饼图
- typescript - 如何在 Typescript 中声明多个相同数据类型的变量,就像我们在 JavaScript 中所做的那样:- var a,b,c;