实现一个电商 SKU 规格禁用逻辑:已选部分规格后,如何计算哪些未选规格选项应当置灰(不可点击)?
思路
给定 SKU 列表(每个 SKU 是一组规格的组合)和当前已选规格,对每一个未选中的规格维度的选项,模拟把它加入已选集合,看是否能匹配到某个存在的 SKU;匹配不到就禁用。
// skus: 所有可选商品,每个是规格值映射,如 { 颜色: '黑色', 容量: '256G' }
// selected: 已选规格,如 { 颜色: '黑色', 容量: undefined }
function getAvailableOptions(skus, selected, allOptions) {
const result = {}
for (const dimension of Object.keys(selected)) {
if (selected[dimension]) continue // 已选中的维度跳过
const options = new Set()
for (const opt of allOptions[dimension]) {
const trial = { ...selected, [dimension]: opt }
if (hasMatch(skus, trial)) options.add(opt) // 选了它之后整体还有货才保留
}
result[dimension] = options // 不在集合中的就是不可选
}
return result
}
// trial 是否能匹配某个 SKU(未选维度不参与匹配)
function hasMatch(skus, trial) {
return skus.some(sku =>
Object.entries(trial).every(([dim, val]) =>
val === undefined || sku[dim] === val
)
)
}关键点
- 未选维度不参与匹配:只看已选维度能否对应到有效 SKU。
- 用「临时加入 → 校验是否存在」的方式,时间复杂度可接受(SKU 数量通常不大)。
- 实际项目可把
allOptions和skus预处理成映射表提升性能。
这是经典电商面试题,核心是「穷举 + 反向校验」:不是单纯判断单个选项,而是判断「选了它之后整体还有没有货」。