商品 SKU 计算,库存不足不能选择
电商项目sku规格计算
假如一件商品的规格如下
// 可以很轻松的知道当前商品一共有 6 种情况
// 部分商品inventory库存是 0,不能选择
// 不能选择的组合一共有 2 种,可以选择的组合有 4 种// 所有规格
const all = [{ id: 1, inventory: 60, specName: '红色-小' },{ id: 2, inventory: 0, specName: '红色-中' },{ id: 3, inventory: 51, specName: '黄色-小' },{ id: 4, inventory: 95, specName: '黄色-中' },{ id: 5, inventory: 0, specName: '蓝色-小' },{ id: 6, inventory: 29, specName: '蓝色-中' }
]
// 可以选择的规格
const canSelect = [['红色', '小'], ['黄色', '小'], ['黄色', '中'], ['蓝色', '中']],// 不能选择的规格
const notSelect = [['红色', '中'], ['蓝色', '小']]
const convertTo2DArray = (arr) => {const n = arr.length;const result = [];for (let i = 0; i < n; i++) {const temp = [...arr.slice(0, i), ...arr.slice(i + 1)];result.push(temp);}return result;
};/** 判断数组2是否包含在数组1中 */
const isArrayContained = (arr1, arr2) => {return arr2.every((x) => arr1.includes(x));
};/** 求两个数组差集 */
const arrayDifference = (arr1, arr2) => {const set1 = new Set(arr1);const set2 = new Set(arr2);return Array.from(new Set([...set1].filter((x) => !set2.has(x))));
};// 假设目前选中了第一款
const select = ['红色', '小'],// 期望结果返回一个数组,包含了所有不能选择的规格,只用把结果返回的项禁用即可
['中', '蓝色']// 计算步骤
const arr = convertTo2DArray(select);
const arr2 = [];
notSelect.forEach((item) => {arr.forEach((item2) => {if (isArrayContained(item, item2)) {arr2.push(...arrayDifference(item, item2));}});
});
console.log(arr2);// 优化版本
function getConflictingSpecs(selected, notSelect) {const conflicts = new Set();notSelect.forEach((forbidden) => {// 检查是否有交集const intersection = selected.filter((spec) => forbidden.includes(spec));if (intersection.length > 0) {// 将冲突的规格加入结果forbidden.forEach((spec) => {if (!selected.includes(spec)) {conflicts.add(spec);}});}});return Array.from(conflicts);
}