处理多规格一般有两种方法:
一、用递归处理商品SKU数据
使用生成 sku数组的长度等于 规格数据数组的长度 -1 作为结束递归的条件
data:
const data = [
{
attrKeyId: 1,
attrKeyName: '',
isImage: false,
saleAttrList: [
{
attrKeyId: '',
attrKeyName: '',
attrValue: '1',
},
{
attrKeyId: '',
attrKeyName: '',
attrValue: '2',
},
],
saleKeyId: 1,
attrKeyAlias: '颜色',
},
{
attrKeyId: 2,
attrKeyName: '',
isImage: false,
saleAttrList: [
{
attrKeyId: '',
attrKeyName: '',
attrValue: '3',
},
{
attrKeyId: '',
attrKeyName: '',
attrValue: '4',
},
],
saleKeyId: 2,
attrKeyAlias: '尺码',
},
{
attrKeyId: 2,
attrKeyName: '',
isImage: false,
saleAttrList: [
{
attrKeyId: '',
attrKeyName: '',
attrValue: '5',
},
{
attrKeyId: '',
attrKeyName: '',
attrValue: '6',
},
{
attrKeyId: '',
attrKeyName: '',
attrValue: '7',
},
],
saleKeyId: 2,
attrKeyAlias: '尺码',
},
// {
// attrKeyId: '',
// attrKeyName: '',
// isImage: false,
// saleAttrList: [
// {
// attrKeyId: '',
// attrKeyName: '',
// attrValue: '5',
// },
// {
// attrKeyId: '',
// attrKeyName: '',
// attrValue: '6',
// },
// ],
// saleKeyId: 2,
// attrKeyAlias: '',
// },
]
// i的作用就是拿到下一个层级的数据
function deepList(nowList, list, i) {
const saleAttrList = list[i].saleAttrList
console.log('saleAttrList', saleAttrList)
// if (list[i].attrKeyAlias == false) {
// deepList([...nowList], list, i + 1)
// return
// }
saleAttrList.map((item) => {
const arr = [...nowList] // [] // [1] //[1,3]
arr.push(item.attrValue)
console.log('arr', arr) // [1] // [1,3] //[1,3,5]
if (i == list.length - 1) {
// 0 != 2 //1 != 2 //2 == 2
console.log('arr=>', arr)
} else {
deepList(arr, list, i + 1) // [1] list 1 [1,2] list 2
}
})
}
deepList([], data, 0)
注释这段可以用 attrKeyAlias判断规格名称还没填写 跳过这个规格 里面的规格不做处理
结果 在data定义个变量 存arr
在这个位置 console.log('arr=>', arr)
上面的写法处理有点麻烦:
进阶递归写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
let names = ['iPhone X', 'iPhone XS']
let colors = ['黑色', '白色']
let storages = ['64g', '256g']
let combine = function (...chunks) {
console.log('...chunks', ...chunks)
let res = []
let helper = function (chunkIndex, prev) {
let chunk = chunks[chunkIndex]
let isLast = chunkIndex === chunks.length - 1
for (let val of chunk) {
let cur = prev.concat(val)
if (isLast) {
// 如果已经处理到数组的最后一项了 则把拼接的结果放入返回值中
res.push(cur)
} else {
helper(chunkIndex + 1, cur)
}
}
}
// 从属性数组下标为 0 开始处理
// 并且此时的 prev 是个空数组
helper(0, [])
return res
}
console.log(combine(names, colors, storages))
let arr = [
['iPhone X', 'iPhone XS'],
['黑色', '白色'],
['64g', '256g'],
]
let combine1 = function (chunks) {
let res = []
console.log('chunks', chunks)
let helper = function (chunkIndex, prev) {
let chunk = chunks[chunkIndex]
let isLast = chunkIndex === chunks.length - 1
for (let val of chunk) {
let cur = prev.concat(val)
console.log('cur', cur)
if (isLast) {
// 如果已经处理到数组的最后一项了 则把拼接的结果放入返回值中
res.push(cur)
} else {
helper(chunkIndex + 1, cur)
}
}
}
// 从属性数组下标为 0 开始处理
// 并且此时的 prev 是个空数组
helper(0, [])
return res
}
console.log('combine1', combine1(arr))
// function name(params) {
// console.log('params', params) // ["iPhone X", "iPhone XS"]
// }
// function name1(...params) {
// console.log('params', params) // [Array(2), Array(2), Array(2)]
// }
// name(names, colors, storages)
// name1(names, colors, storages)
</script>
</body>
</html>
...params 可以把 多个参数组成一个数组
function name1(...params) {
console.log('params', params) // [Array(2), Array(2), Array(2)]
}
name1(1, 2, 3, 4, 5) [1, 2, 3, 4, 5]
第二种:笛卡尔积
商品sku笛卡尔积
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 商品属性
const attributes = {
color: {
name: '颜色',
values: [
{ name: '红色', value: 'red' },
{ name: '蓝色', value: 'blue' },
{ name: '绿色', value: 'green' },
],
},
size: {
name: '尺寸',
values: [
{ name: 'S', value: 's' },
{ name: 'M', value: 'm' },
{ name: 'L', value: 'l' },
],
},
}
console.log('Object.values(attributes)', Object.values(attributes))
const attributeValues = Object.values(attributes).map(
(attr) => attr.values
)
console.log(attributeValues)
// [
// [
// { name: '红色', value: 'red' },
// { name: '蓝色', value: 'blue' },
// { name: '绿色', value: 'green' },
// ],
// [
// { name: 'S', value: 's' },
// { name: 'M', value: 'm' },
// { name: 'L', value: 'l' },
// ]
// ]
const cartesianProduct = (...arrays) =>
arrays.reduce(
(acc, curr) => acc.flatMap((a) => curr.map((c) => [...a, c])),
[[]]
)
const attributeCombinations = cartesianProduct(...attributeValues)
console.log('attributeCombinations', attributeCombinations)
</script>
</body>
</html>
flatMap 方法:
js里面flatMap和map的区别
多层数据结构转单层时用flatmap,单层转单层或者多层转多层用map
const arr1 = [1, 2, [3], [4, 5], 6, []];
const flattened = arr1.flatMap(num => num);
console.log(flattened);
// Expected output: Array [1, 2, 3, 4, 5, 6]