2025年sku排列算法实现商品规格属性组合

sku排列算法实现商品规格属性组合背景 前两年做过一个电商系统的新建商品模块 记忆中比较有难点的是在新增商品的 sku 规格时 需要把每个规格名称下的规格属性一一组合起来 因此在这里稍微的写个小 demo 记录下这种规格属性组合的思路 数据结构 假设一个 sku 的集合数据结构是这样的 name 内存

大家好,我是讯享网,很高兴认识大家。

背景

前两年做过一个电商系统的新建商品模块,记忆中比较有难点的是在新增商品的sku规格时,需要把每个规格名称下的规格属性一一组合起来。因此在这里稍微的写个小demo记录下这种规格属性组合的思路😁

数据结构

// 假设一个sku的集合数据结构是这样的 /* [ { name: '内存', // 规格名称 // 规格属性列表 list: [ { name: '128GB' }, { name: '256GB' }, { name: '512GB' }, ] }, ... ] */

讯享网

新增一个data.json文件用于存放模拟数据

讯享网// data.json export default [ { "name": "机型", "list": [ { "name": "iPhone 13"}, { "name": "iPhone 14"} ] }, { "name": "颜色", "list": [ { "name": "蓝色"}, { "name": "白色"} ] }, { "name": "存储容量", "list": [ { "name": "64GB"}, { "name": "128GB"} ] } ]

实现商品规格属性组合数据处理

将sku集合的属性列表 -- 集合成这样的格式[ [ {...},{...},...],[{...},{...} ] ] 二维数组的数

const sku_list = [] function composeSkuList() { for(const { list } of skuData) { sku_list.push(list) } } composeSkuList()

处理的结果打印是这样的:


讯享网

 sku排列算法 -- 将二维数组使用扩展运算符传入参数,调用数组的reduce循环,在内部使用双重循环concat拼接后存储到全局变量中

讯享网function cartesianProductOf () { return Array.prototype.reduce.call(arguments, function(a, b) { const result = [] // 存储拼接的结果 a.forEach(item_a => { b.forEach(item_b => { result.push(item_a.concat(item_b)) }) }) return result }, [[]]) } console.log(cartesianProductOf(...sku_list))

打印的结果是这样的

 

现在构造渲染的表格数据,调用排列sku的方法

function composeTableData (sku_list) { // 获取组合好的sku规格数据 const arr = cartesianProductOf(...sku_list) return arr.map(item => { return { sku: item, // 组合好的规格[{...},{...}] oprice: 10, // 销售价 cprice: 5, // 成本价 stock: 100 // 库存 } }) }

以上就是处理商品规格组合的逻辑

结合表格展示商品规格属性组合

下面是完整的代码

讯享网<!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>
  <style>
    th, td{
      padding: 12px;
    }
  </style>
</head>
<body>
  <div>
    <table border cellspacing="0" cellpadding="0" id="table"></table>
  </div>
</body>
</html>
<script type="module">
// 处理数据
// 假设一个sku的集合数据结构是这样的
  /*
  [
    { 
      name: '内存', // 规格名称
      // 规格属性列表
      list: [
        { name: '128GB' },
        { name: '256GB' },
        { name: '512GB' },
      ]
    },
    ...
  ]
*/

 // 引入数据
 import skuData from './data.js'

let sku_list = [] // 村粗规格属性列表
let tableData = [] // 存储表格数据

let colSkuValue = [] // 存储商品规格渲染列的名称

// 先将sku集合的属性列表 -- 集合成这样的格式[[{...},{...},...],[{...},{...}]] 二维数组的数组对象结构格式
function composeSkuList() {
  let skuList = []
  for(const { list } of skuData) {
    skuList.push(list)
  }
  return skuList
}

// sku排列算法 -- 将二维数组使用扩展运算符传入参数,调用数组的reduce循环,在内部使用双重循环concat拼接后存储到全局变量中
function cartesianProductOf () {
  return Array.prototype.reduce.call(arguments, function(a, b) {
    const result = []  // 存储拼接的结果
    a.forEach(item_a => {
      b.forEach(item_b => { 
        result.push(item_a.concat(item_b))
      })
    })
  return result
  }, [[]])
 }

// 构造渲染的表格数据
function composeTableData (data) {
  console.log(data, 'data')
  // 获取组合好的sku规格数据
  const arr = cartesianProductOf(...data)
  return arr.map(item => {
    return {
      sku: item,  // 组合好的规格[{...},{...}]
      oprice: 10, // 销售价
      cprice: 5, // 成本价
      stock: 100 // 库存
    }
  })
}

// 构造需要渲染商品规格名称的列
function composeColSkuValue () {
  return skuData.map(item => item.name)
}

sku_list = composeSkuList()
tableData = composeTableData(sku_list)
colSkuValue = composeColSkuValue()
console.log(tableData, 'composeTableData')
console.log(colSkuValue, 'colSkuValuecolSkuValue')



// 渲染表格的处理方法
let column = [
  {name: "商品规格",rowspan: 1,colspan: 1,width: ""},
  {name: "销售价",rowspan: 2,width: "80"},
  {name: "成本价",rowspan: 2,width: "80"},
  {name: "库存",rowspan: 2,width: "80"}
]
let table = document.getElementById('table')
const thead = document.createElement('thead');
table.appendChild(thead)
const theadTr = document.createElement('tr')
const colSkuTr = document.createElement('tr')
thead.append(theadTr)
thead.append(colSkuTr)
column[0].colspan = colSkuValue.length // 第一列随着有多少个规格名称就跨几列
// S 创建表头
for(let i = 0; i < column.length; i++) {
  const th = document.createElement('th')
  th.innerHTML = column[i].name
  th.rowSpan = column[i].rowspan
  th.colSpan = column[i].colspan
  th.width = column[i].width
  theadTr.appendChild(th)
}
for(let i = 0; i < colSkuValue.length; i++) {
  const th = document.createElement('th')
  th.innerHTML = colSkuValue[i]
  colSkuTr.appendChild(th)
}
// E 创建表头

// S 创建表体
const tbody = document.createElement('tbody')
const keyArr = ['oprice', 'cprice', 'stock']
for(let i = 0; i < tableData.length; i++) {
const tbodyTr = document.createElement('tr')
for(let skuIndex = 0; skuIndex < tableData[i].sku.length; skuIndex++) {
  const sku = tableData[i].sku[skuIndex]
  const skuTd = document.createElement('td')
  skuTd.innerHTML = sku.name
  tbodyTr.appendChild(skuTd)
}
for(const key of keyArr) {
  const td = document.createElement('td')
  td.innerHTML = tableData[i][key]
  tbodyTr.appendChild(td)
}
tbody.appendChild(tbodyTr)
}
table.appendChild(tbody)
// E 创建表体
</script>

最后展示的结果如下图

~~~end~~~

小讯
上一篇 2025-04-08 19:54
下一篇 2025-03-25 16:06

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/59222.html