前端电商 sku 的全排列算法

为了界面可以好看一点,我们使用 Vant 组件库的 sku 组件(安装,使用都很简单,就跟普通的组件库一样)。😀😀😀😀😀
代码如下

<template>
  <div class="">
    <div class="sku-container">
      <van-sku
        v-model="showBase"
        :sku="sku"
        :goods="goods_info"
        :goods-id="goods_id"
        :hide-stock="sku.hide_stock"
        :quota="quota"
        :quota-used="quota_used"
        :initial-sku="initialSku"
        reset-stepper-on-hide
        reset-selected-sku-on-hide
        disable-stepper-input
        :close-on-click-overlay="closeOnClickOverlay"
        :custom-sku-validator="customSkuValidator"
        @buy-clicked="onBuyClicked"
        @add-cart="onAddCartClicked"
      />
      <van-button block type="primary" @click="showBase = true"> </van-button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true,
      sku: {
        tree: [
          {
            k: "名称",
            k_id: "1",
            v: [
              {
                id: "30349",
                name: "iPhone X",
                imgUrl:"https://img10.360buyimg.com/n1/s450x450_jfs/t1/46210/19/11279/467217/5d81c5deE4e74f60d/39ee1e4d741b150a.png",
              },
              {
                id: "1215",
                name: "iPhone XS",
                imgUrl:"https://img13.360buyimg.com/n1/s450x450_jfs/t1/5064/31/3461/142209/5b997c0eE8b26d23e/8788a4743af36f36.jpg",
              },
            ],
            k_s: "s1",
            count: 2,
          },
          {
            k: "颜色",
            k_id: "2",
            v: [
              {
                id: "1193",
                name: "黑色",
              },
              {
                id: "1194",
                name: "白色",
              },
            ],
            k_s: "s2",
            count: 2,
          },
        ],
        list: [
          {
            id: 2259,
            price: 120,
            discount: 122,
            s1: "1215",
            s2: "1193",
            s3: "0",
            s4: "0",
            s5: "0",
            stock_num: 20,
            goods_id: 946755,
          },
          {
            id: 2260,
            price: 110,
            discount: 112,
            s1: "1215",
            s2: "1194",
            s3: "0",
            s4: "0",
            s5: "0",
            stock_num: 2,
            goods_id: 946755,
          },
          {
            id: 2257,
            price: 130,
            discount: 132,
            s1: "30349",
            s2: "1193",
            s3: "0",
            s4: "0",
            s5: "0",
            stock_num: 40,
            goods_id: 946755,
          },
          {
            id: 2258,
            price: 100,
            discount: 100,
            s1: "30349",
            s2: "1194",
            s3: "0",
            s4: "0",
            s5: "0",
            stock_num: 50,
            goods_id: 946755,
          },
        ],
        price: "5.00",
        stock_num: 227,
        none_sku: false,
        hide_stock: false,
      },
      goods_id: "946755",
      quota: 3,
      quota_used: 0,
      goods_info: {
        title: "测试商品A",
        picture:
          "https://img.yzcdn.cn/upload_files/2017/03/16/Fs_OMbSFPa183sBwvG_94llUYiLa.jpeg?imageView2/2/w/100/h/100/q/75/format/jpg", //图片这个我有点混乱
      },
      initialSku: {
        s1: "0001",
        s2: "1001",
        selectedNum: 1,
      },
      showBase: true,
      showCustom: false,
      showStepper: false,
      showSoldout: false,
      closeOnClickOverlay: true,
      initialSku: {
        s1: "30349",
        s2: "1193",
        selectedNum: 3,
      },
      customSkuValidator: () => "请选择xxx!",
    };
  },
  methods: {
    onBuyClicked(sku) {
      this.$toast("buy:" + JSON.stringify(sku));
      console.log(JSON.stringify(sku));
    },
    onAddCartClicked(sku) {
      this.$toast("add cart:" + JSON.stringify(sku));
    },
  },
};
</script>

运行之后的样子

在这里插入图片描述

list: [
          {
            id: 2259,
            price: 120,
            discount: 122,
            s1: "1215",
            s2: "1193",
            s3: "0",
            s4: "0",
            s5: "0",
            stock_num: 20,
            goods_id: 946755,
          },
          {
            id: 2260,
            price: 110,
            discount: 112,
            s1: "1215",
            s2: "1194",
            s3: "0",
            s4: "0",
            s5: "0",
            stock_num: 2,
            goods_id: 946755,
          },
          {
            id: 2257,
            price: 130,
            discount: 132,
            s1: "30349",
            s2: "1193",
            s3: "0",
            s4: "0",
            s5: "0",
            stock_num: 40,
            goods_id: 946755,
          },
          {
            id: 2258,
            price: 100,
            discount: 100,
            s1: "30349",
            s2: "1194",
            s3: "0",
            s4: "0",
            s5: "0",
            stock_num: 50,
            goods_id: 946755,
          },
        ],

这一段是列出商品组合的所有情况。(如果是一两件商品还好,但是如果商品数目多的情况下就很麻烦了)
所以,我们单独写一个文件来模拟这个场景😄😄😄

let names = ["iPhone X", "iPhone XS"]

let colors = ["黑色", "白色"]

需要把他们的所有组合穷举出来,最终得到这样一个数组:

[
  [ 'iPhone X', '黑色' ], 
  [ 'iPhone X', '白色' ], 
  [ 'iPhone XS', '黑色' ],
  [ 'iPhone XS', '白色' ] 
]

比如我们目前的属性数组就是:namescolors,首先处理 names
数组,很显然对于每个属性数组,都需要去遍历它,然后一个一个选择后再去和 下一个数组的每一项进行组合。 递归函数接受两个参数: index
对应当前正在处理的下标,是 names 还是 colorsprev 上一次递归已经拼接成的结果,比如 [‘iPhone X’]。
进入递归函数: 处理属性数组的下标0:假设我们在第一次循环中选择了 iPhone XS,此时我们有一个未完成的结果状态,假设是
prev,此时 prev = [‘iPhone XS’]。 处理属性数组的下标1:那么就处理到 colors 数组的了,并且我们拥有
prev,在遍历 colors 的时候继续递归的去把 prev 拼接成 prev.concat(color),也就是 [‘iPhone XS’, ‘黑色’] 这样继续把这个 prev 交给下一次递归。 以此类推下去,我们就可以得到一个完整的组合后的数组。

let names = ["iPhone X", "iPhone XS"]

let colors = ["黑色", "白色"]

let combine = function (...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))

这就是前端电商的 sku 算法
(笔者刚刚学习算法,文章若有错误,望各位指正)
🥰🥰🥰🥰🥰🥰🥰🥰🥰

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值