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>

 

posted @ 2023-08-31 11:00  叶乘风  阅读(99)  评论(0编辑  收藏  举报