刚刚开始深入研究JavaScript中的对象排序数组,并给出了以下片段。这个代码是否有可能以某种方式进行性能优化,或者这看起来总体上是合法的?
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);
工作流程:
- 每个产品的非结构化类别
- 按升序排序
- 根据类别标题在单独的数组中进行筛选
我目前最担心的是以下行:
.map(({ title }) => (
products.filter(({ category: { title: cTitle } }) => title === cTitle)
));
您使用priority
对数组进行间接排序,但不必经历所有步骤。你可以在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; }
您可以对此进行进一步优化,并且根据输入的形状需要注意一些边缘情况。
总的来说,您可以做的一件事是将类别规范化为一个单独的集合,并引用产品中的类别id。这将消除在不同对象中具有相同类别标题和不同优先级的可能性。
您还没有以确保排序顺序的方式处理具有相同优先级的多个类别的排序行为,您应该按优先级排序,按标题排序以解决此问题。这个排序调用依赖于浏览器对sort()的实现,因此应该得到很好的优化。
您的算法在乘积上进行映射,并为映射的每次迭代过滤乘积,这是O(n^2)时间复杂性。将其作为O(n)算法将为您在大型数据集上节省大量时间。
我添加了一个片段,它在排序之前使用Map来消除类别的重复,并在使用Map进行分组之前缓存类别数组索引。诚然,与为产品分组找到单程算法的总体改进相比,这些优化非常小。
根据已删除重复数据并排序的类别数组创建一个空的二维数组。然后,我们对products数组进行迭代,并将产品添加到适当的类别数组中。
我们使排序更快、更准确;其他一切现在都是在摊销后的固定时间内完成的。
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)