2023-08-31 js 笛卡尔积之商品规格组合(递归)
假设我们的商品规格数据为:
let arr = [ { name: '材质', value: ['花岗岩','玄武岩'], }, { name: '体积', value: ['10克'], }, { name: '颜色', value: ['白色'], }, ];
我们想要的最终数据:
[['花岗岩', '10克', '白色'],['玄武岩', '10克', '白色']]
实现代码:
function combineSpecs(specs) { if (specs.length === 0) { return [ [] ]; } else { const [head, ...tail] = specs; const rest = this.combineSpecs(tail); const pairs = head.value.map(value => rest.map(r => [value, ...r])); return [].concat(...pairs); } }; let arr = [ { name: '材质', value: ['花岗岩','玄武岩'], }, { name: '体积', value: ['10克'], }, { name: '颜色', value: ['白色'], }, ]; let arr2 = this.combineSpecs(arr); console.log('最终结果',arr2);
关键就是这个combineSpecs函数,它把数组里面的所有值进行了组合,才得出我们想要的结果。
============== 2024-08-16:如果你的数据格式是数组嵌套对象,如下: ==============
let arr = [
{
name: '颜色',
value: 'color',
content: ['red', 'color', 'blue'],
},
{
name: '名称',
value: 'name',
content: ['毛巾', '抹布'],
},
{
name: '类型',
value: 'type',
content: ['正常', '异常'],
},
];
想要把每项都组合起来,如下:

那么需要修改一下函数,如下:
function combineSpecs(specs) {
if (specs.length === 0) {
return [
[]
];
} else {
const [head, ...tail] = specs;
const rest = this.combineSpecs(tail);
const pairs = head.content.map(item =>
rest.map(r => ({ ...r, [head.value]: item }))
);
return [].concat(...pairs);
}
};
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> </body> </html> <script> function combineSpecs(specs) { if (specs.length === 0) { return [ [] ]; } else { const [head, ...tail] = specs; const rest = this.combineSpecs(tail); const pairs = head.content.map(item => rest.map(r => ({ ...r, [head.value]: item })) ); return [].concat(...pairs); } }; let arr = [ { name: '颜色', value: 'color', content: ['red', 'color', 'blue'], }, { name: '名称', value: 'name', content: ['毛巾', '抹布'], }, { name: '类型', value: 'type', content: ['正常', '异常'], }, ]; let arr2 = this.combineSpecs(arr); console.log('最终结果', arr2); </script>

浙公网安备 33010602011771号