我有一些我在紧要关头写的JavaScript,但我认为它可以由比我聪明的人大大优化。此代码在相对较小的对象上运行,但运行时间相当长,因此值得一试:
/**
* Determine the maximum quantity we can show (ever) for these size/color combos
*
* @return int=settings.limitedStockThreshold
*/
function getMaxDefaultQuantity() {
var max_default_quantity = 1;
if (inventory && inventory.sizes) {
sizecolor_combo_loop:
for (var key in inventory.sizes) {
if (inventory.sizes[key].combos) {
for (var key2 in inventory.sizes[key].combos) {
var sizecolor_combo = inventory.sizes[key].combos[key2];
if (isBackorderable(sizecolor_combo)) {
//if even one is backorderable, we can break out
max_default_quantity = settings.limitedStockThreshold;
break sizecolor_combo_loop;
} else {
//not backorderable, get largest quantity (sizecolor_combo or max_default_quantity)
var qoh = parseInt(sizecolor_combo.quantityOnHand || 1);
if (qoh > max_default_quantity) {
max_default_quantity = qoh;
};
};
};
};
};
};
return Math.min(max_default_quantity, settings.limitedStockThreshold);
};
首先,库存是通过JSON返回的对象。它具有 inventory.sizes 属性,其中包含产品的所有可用大小。每种尺寸都有一个属性 inventory.sizes.combos ,它会映射到一个尺寸的所有可用颜色。每个组合还有一个属性 quantityOnHand ,用于说明该特定组合的可用数量。 (返回的JSON结构无法修改)
代码的作用是遍历每个大小,然后是每个大小的组合。然后检查大小颜色组合是否可以反向(通过另一种方法)。如果任何组合都是可退役的,我们可以停止,因为默认数量是在其他地方定义的。如果组合不可后退,则max_default_quantity是我们找到的最大quantityOnHand(最多使用settings.limitedStockThreshold)。
我真的不喜欢嵌套的for循环,我对数学和默认值的处理感觉过于复杂。
此外,整个函数包含在一个更大的jQuery对象中,如果这有助于清理它。
答案 0 :(得分:0)
不幸的是,如果你不得不支持旧浏览器,那么JavaScript在优雅的集合处理能力方面没有太大的作用,所以没有其他库的帮助,你编写的嵌套循环就是要走的路。 。您可以考虑将值预先计算在服务器端,也就是缓存,并将其包含在JSON中,以避免不得不一次又一次地运行相同的计算。
答案 1 :(得分:0)
您是否考虑过使用map-reduce?请参阅功能方法的live示例。
此特定示例使用underscore.js,因此我们可以将其保持在优雅的级别,而无需实现细节。
function doStuff(inventory) {
var max = settings.limitedStockThreshold;
if (!(inventory && inventory.sizes)) return;
var quantity = _(inventory.sizes).chain()
.filter(function(value) {
return value.combos;
})
.map(function(value) {
return _(value.combos).chain()
.map(function(value) {
return isBackorderable(value) ? max : value.quantityOnHand;
})
.max().value();
})
.max().value();
return Math.min(quantity, max);
}
至于解释:
我们设置inventory.sizes并删除任何不包含组合的内容。然后,我们将每个尺寸映射到它的最大颜色数量。我们这样做将每个组合映射到其数量或最大数量(如果可回溯)。然后我们采取最大值。
最后,我们采用每个大小最大的maxQuantities集。
我们仍然有效地进行双循环,因为我们在集合上取两个.max
但它看起来并不脏。
还有一些if check that that that that that。
[编辑]
我很确定上面的代码可以进行更多优化。但这是另一种看待它的方式。