Quiero completar orders que es una matriz de tipo Order . El resultado esperado es orders=[{id:1,qt:4},{id:2, qt:2},{id:3,qt:2}] . ¿Cómo hacerlo en TypeScript? soy nuevo en esto
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[] = []; Para aquellos que quieran saber cómo se obtiene orders=[{id:1,qt:4},{id:2, qt:2},{id:3,qt:2}] .
En el cart :
id:1 ) es qt:4id:2 ) es qt:2id:3 ) es qt:2 Entonces, al usar el carrito, tengo que obtener orders=[{id:1,qt:4},{id:2, qt:2},{id:3,qt:2}] . Debería ser claro.
Dado que está buscando una solución "similar a LINQ", probablemente desee utilizar las funciones de orden superior como map / filter / reduce .
Estrictamente, su problema no se puede resolver únicamente con proyecciones LINQ. Esos simplemente representan map ( Select ), concatMap / flatMap ( SelectMany ) y zip ( Zip ). Su problema consiste en contar las ocurrencias de cada id en toda la matriz.
Casi todos los problemas de manipulación de datos se pueden resolver con pliegues de orden superior, es decir, reduce en javascript land, Aggregate en C# land. Este no es una excepción. Lo primero que debe hacer es contar las ocurrencias de cada id y construir un objeto contador .
cart.reduce((acc, { id }) => { acc[id] = (acc[id] ?? 0) + 1; return acc; }, {} as Record<number, number>); Esencialmente, comienza la operación de plegado con un objeto vacío, luego agrega cada id y su recuento de ocurrencias. Cada vez que se encuentra una id en la matriz del cart , incrementa su conteo en el objeto. Si la id aún no existe en el objeto acumulado, la fusión nula ( acc[id] ?? 0 ) usa 0 y lo incrementa en su lugar.
Esto te dará-
{ '1': 4, '2': 2, '3': 2 }Ahora, necesitas convertir esto en-
[ { id: 1, qt: 4 }, { id: 2, qt: 2 }, { id: 3, qt: 2 } ] Para eso, use Object.entries en el resultado del pliegue para obtener-
> Object.entries({ '1': 4, '2': 2, '3': 2 }) [ [ '1', 4 ], [ '2', 2 ], [ '3', 2 ] ] Finalmente, un map simple es todo lo que necesita-
Object.entries(...).map(([id, qt]) => ({ id: Number(id), qt }))Combinando todo eso, tienes-
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 })); Una cosa a tener en cuenta aquí es que Object.entries es bastante ineficiente ya que crea una matriz en lugar de un iterador. Si le gusta la eficiencia, ejecute una versión de iterador de Object.entries y utilícela en su lugar, usando funciones de generador :
function* objEntries<T>(x: Record<string, T>): IterableIterator<[string, T]> { for (const k in x) { yield [k, x[k]]; } }