Acabo de empezar a sumergirme en la matriz de clasificación de objetos en JavaScript, habiendo encontrado el siguiente fragmento. ¿Existe la posibilidad de que este código pueda optimizarse de alguna manera para el rendimiento o parece generalmente legítimo?
const products = [ { title: "Test product1", description: "Test description", price: 5, category: { title: 'hot_dishes', priority: 2 }, ru: { title: "Тестовый продукт", description: "пошел на хуй" } }, { title: "Test product2", description: "Test description", price: 5, category: { title: 'dessert', priority: 1 }, ru: { title: "Тестовый продукт", description: "пошел на хуй" } } ]; const sorted = products .map(({ category }) => category) .sort((a, b) => parseFloat(a.priority) - parseFloat(b.priority)) .map(({ title }) => ( products.filter(({ category: { title: cTitle } }) => title === cTitle) )); console.log(sorted);Flujo de trabajo:
Mi mayor preocupación actual es sobre la siguiente línea:
.map(({ title }) => ( products.filter(({ category: { title: cTitle } }) => title === cTitle) ));Está clasificando indirectamente la matriz usando la priority , pero no tiene que seguir todos los pasos. También puede usar ordenar en los products
const sorted = products.sort((a, b) => a.category.priority - b.category.priority); const products = [ { title: "Test product1", description: "Test description", price: 5, category: { title: "hot_dishes", priority: 2 }, ru: { title: "Тестовый продукт", description: "пошел на хуй" } }, { title: "Test product2", description: "Test description", price: 5, category: { title: "dessert", priority: 1 }, ru: { title: "Тестовый продукт", description: "пошел на хуй" } } ]; const sorted = products.sort((a, b) => a.category.priority - b.category.priority); console.log(sorted); /* This is not a part of answer. It is just to give the output full height. So IGNORE IT */ .as-console-wrapper { max-height: 100% !important; top: 0; }Puede optimizar esto aún más, y hay algunos casos extremos que debe tener en cuenta en función de la forma de su entrada.
Algo que podría hacer en general es normalizar las categorías en una colección separada y hacer referencia a la identificación de la categoría en el producto. Esto eliminaría la posibilidad de tener el mismo título de categoría con diferentes prioridades en diferentes objetos.
Tampoco ha manejado el comportamiento de clasificación de varias categorías con la misma prioridad de una manera que garantice el orden de clasificación, debe ordenar por prioridad y alfa por título para solucionarlo. Esta llamada de clasificación se basa en la implementación de sort() del navegador y, por lo tanto, debe estar bien optimizada.
Su algoritmo mapea sobre el producto y filtra el producto para cada iteración del mapa, que es una complejidad de tiempo O (n ^ 2). Hacer de esto un algoritmo O(n) le ahorrará mucho tiempo en un gran conjunto de datos.
Agregué un fragmento que elimina los duplicados de las categorías usando un Mapa antes de ordenar, y almacena en caché el índice de la matriz de categorías antes de agrupar usando un Mapa allí también. Esas optimizaciones son ciertamente bastante pequeñas en comparación con la mejora general de encontrar un algoritmo de un solo paso para agrupar sus productos.
Se crea una matriz bidimensional vacía a partir de la matriz de categorías deduplicada y ordenada. Luego iteramos sobre la matriz de productos y agregamos los productos a la matriz de categorías adecuada.
Hemos hecho la ordenación un poco más rápida y precisa; todo lo demás se realiza ahora en tiempo constante amortizado.
const products = [{ title: "Test product1", description: "Test description", price: 5, category: { title: 'hot_dishes', priority: 2 }, ru: { title: "Тестовый продукт", description: "пошел на хуй" } }, { title: "Test product2", description: "Test description", price: 5, category: { title: 'dessert', priority: 1 }, ru: { title: "Тестовый продукт", description: "пошел на хуй" } } ]; const categoryComparator = (a, b) => { const priorityComparison = parseFloat(a.priority) - parseFloat(b.priority) if ( priorityComparison !== 0 ) return priorityComparison return a.title.localeCompare(b) } const categoryMap = new Map() products.forEach(product => categoryMap.set(product.category.title, product.category) ) const sortedCategories = Array.from(categoryMap, ([title, category]) => category) .sort(categoryComparator) .map(category => category.title) const categoryIndexMap = new Map([...new Set(sortedCategories)].map((category, index) => [category, index])) const categorizedProductArrays = Array.from({ length: categoryIndexMap.size }, i => []) products.forEach((product) => categorizedProductArrays[categoryIndexMap.get(product.category.title)].push(product)) console.log(categorizedProductArrays)