商城后台-sku

179 阅读1分钟

处理多规格一般有两种方法:

一、用递归处理商品SKU数据

使用生成 sku数组的长度等于 规格数据数组的长度 -1 作为结束递归的条件 image.png

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)

上面的写法处理有点麻烦:

进阶递归写法

image.png

image.png

<!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笛卡尔积

image.png

<!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]