分享一个关于前端商品SKU组合算法,希望能够帮助到大家

34,665 阅读1分钟

商品规格参数

const attrList = [
  { id: 1, name: "颜色", attrs: [ { id: 100, name: "紫色" }, { id: 101, name: "黑色" }, { id: 102, name: "白色" }, { id: 103, name: "红色" } ] },
  { id: 2, name: "套餐", attrs: [ { id: 200, name: "套餐一" }, { id: 201, name: "套餐二" }, { id: 202, name: "套餐三" } ] },
  { id: 3, name: "内存", attrs: [ { id: 300, name: "64G" }, { id: 301, name: "128G" }, { id: 302, name: "256G" } ] }
]

商品组合 sku

  • 随机字符,生成唯一值
const uuid = (len, radix = 62) => {
  const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("")
  const uuid = []
  if (len) {
    for (let i = 0; i < len; i++) {
      uuid[i] = chars[Math.floor(Math.random() * radix)]
    }
  } else {
    let r
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-"
    uuid[14] = "4"
    for (let i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = Math.floor(Math.random() * 16)
        uuid[i] = chars[(i === 19) ? ((r % 4) % 8) + 8 : r]
      }
    }
  }
  return uuid.join("")
}
  • 获取全部规格的属性
const list = attrList.map(it => it.attrs)
// 得到一个二维数组
// [
//   [
//     { id: 100, name: "紫色" }, { id: 101, name: "黑色" }, { id: 102, name: "白色" }, { id: 103, name: "红色" }
//   ],
//   [
//     { id: 200, name: "套餐一" }, { id: 201, name: "套餐二" }, { id: 202, name: "套餐三" }
//   ],
//   [
//     { id: 300, name: "64G" }, { id: 301, name: "128G" }, { id: 302, name: "256G" }
//   ]
// ]
  • 通过得到的二维数组,遍历出全部组合的sku

    • 1,使用 reduce + flatMap + map 方法 (推荐使用)
      const computedSkuFn = (attrList) => {
        attrList.reduce((a, b) => {
          return a.flatMap(x => b.map(y => [ ...x, y ]))
        }, [ [] ])
      }
      
    • 2,使用递归的方式
      const computedSkuFn = (attrList) => {
        let results = []
        let result = []
        const _sku = (arr, index) => {
          for (let i = 0; i < arr[index].length; i++) {
            result[index] = arr[index][i].id
            (index !== arr.length - 1) ? _sku(arr, index + 1) : results.push(result.join(","))
          }
        }
        _sku(attrList, 0)
        return results
      }
      
  • 整合 sku 列表

const skuList = computedSkuFn(list).map(item => {
  return {
    id: uuid(8),
    sku: item.map(i => i.id),
    total: 0
  }
})

最终效果如图

QQ截图20210926100951.png

最后

3.gif