JS数组 组合方式 在线求写法!!
发布于 8 年前 作者 Wizzercn 6525 次浏览 来自 问答

var arr=[[“颜色:白色”,“颜色:黑色”],[“尺码:10”,“尺码:20”],[“材质:钻石”,“材质:水晶”,“材质:玛瑙”]];

js 写12组 组合怎么写?在线求,困扰我2天了

升级版:

var spec=[[{“spec_name”:“颜色”,“spec_type”:“1”,“spec_id”:“5”,“spec_value_id”:“11”,“spec_value_name”:“白色”},{“spec_name”:“颜色”,“spec_type”:“1”,“spec_id”:“5”,“spec_value_id”:“12”,“spec_value_name”:“黑色”}],[{“spec_name”:“尺码”,“spec_type”:“0”,“spec_id”:“6”,“spec_value_id”:“9”,“spec_value_name”:“10”},{“spec_name”:“尺码”,“spec_type”:“0”,“spec_id”:“6”,“spec_value_id”:“10”,“spec_value_name”:“20”}],[{“spec_name”:“材质”,“spec_type”:“0”,“spec_id”:“7”,“spec_value_id”:“13”,“spec_value_name”:“钻石”},{“spec_name”:“材质”,“spec_type”:“0”,“spec_id”:“7”,“spec_value_id”:“14”,“spec_value_name”:“水晶”},{“spec_name”:“材质”,“spec_type”:“0”,“spec_id”:“7”,“spec_value_id”:“15”,“spec_value_name”:“玛瑙”}]] 最终结果就是输出12种商品组合。。。。写法要支持1个数组、N个数组。。。

5 回复

试试lodash呗,我翻译了 lodash4的中文文档 ,可以很方便的处理这样的事情 http://lodash.think2011.net/fromPairs

QQ20160228-1@2x.png

仅供参考, 可能有更好的算法

function getProducts(specs) {
    if (!specs || specs.length == 0) {
        return [];
    } else {
        return joinSpec([[]], specs, 0, specs.length-1);
    }
    function joinSpec(prevProducts, specs, i, max) {
        var currentProducts = [], currentProduct, currentSpecs = specs[i];
        if ( i > max ) {
            return prevProducts;
        }
        prevProducts.forEach(function(prevProduct) {
            currentSpecs.forEach(function(spec) {
                currentProduct = prevProduct.slice(0);
                currentProduct.push(spec);
                currentProducts.push(currentProduct);
            });
        });
        return joinSpec(currentProducts, specs, ++i, max);
    }
}

var specs = [[{"spec_name":"颜色","spec_type":"1","spec_id":"5","spec_value_id":"11","spec_value_name":"白色"},{"spec_name":"颜色","spec_type":"1","spec_id":"5","spec_value_id":"12","spec_value_name":"黑色"}],[{"spec_name":"尺码","spec_type":"0","spec_id":"6","spec_value_id":"9","spec_value_name":"10"},{"spec_name":"尺码","spec_type":"0","spec_id":"6","spec_value_id":"10","spec_value_name":"20"}],[{"spec_name":"材质","spec_type":"0","spec_id":"7","spec_value_id":"13","spec_value_name":"钻石"},{"spec_name":"材质","spec_type":"0","spec_id":"7","spec_value_id":"14","spec_value_name":"水晶"},{"spec_name":"材质","spec_type":"0","spec_id":"7","spec_value_id":"15","spec_value_name":"玛瑙"}]];

console.log(getProducts(specs));

William17 楼上太牛了,结果正确,不过前台forEach不能用,我改成 $.each 遍历,多谢了。。。另外也谢1楼,虽然不是我想要的效果。。~~:)

这是典型的求笛卡尔积问题,@William17的算法可以解决一般性问题,足够用了,赞一个,不过如果参数中选项较多、处理数量多的话就比较慢了,下面给出的算法用6*6数组跑了200万次的benchmark测试了一下,效率大概要快到2~3倍:

function getProducts(specs) {
    specs = specs || [];
    var n = specs.length;
    if(n === 0) { return [] }
    if(n === 1) { return specs[0] }

    var save = function() {
        var m = groups.length, c = [];
        while(m--) { c[m] = groups[m] }
        rtn.push(c);
    }
    var i=0, len=0, counter = [], groups = [], rtn = [];

    for (; i < n; i++) {
      counter[i] = 0;
      groups[i] = specs[i][0];
    }
    save();

    while(true) {
      i = n - 1, len = specs[i].length;
      if (++counter[i] >= len) {
          while (counter[i] >= len) {
            if (i === 0) { return rtn }
            groups[i] = specs[i][0];
            counter[i--] = 0;
            counter[i]++;
            len = specs[i].length;
          }
      }
      groups[i] = specs[i][counter[i]];
      save();
    }
}
var specs = [[{"spec_name":"颜色","spec_type":"1","spec_id":"5","spec_value_id":"11","spec_value_name":"白色"},{"spec_name":"颜色","spec_type":"1","spec_id":"5","spec_value_id":"12","spec_value_name":"黑色"}],[{"spec_name":"尺码","spec_type":"0","spec_id":"6","spec_value_id":"9","spec_value_name":"10"},{"spec_name":"尺码","spec_type":"0","spec_id":"6","spec_value_id":"10","spec_value_name":"20"}],[{"spec_name":"材质","spec_type":"0","spec_id":"7","spec_value_id":"13","spec_value_name":"钻石"},{"spec_name":"材质","spec_type":"0","spec_id":"7","spec_value_id":"14","spec_value_name":"水晶"},{"spec_name":"材质","spec_type":"0","spec_id":"7","spec_value_id":"15","spec_value_name":"玛瑙"}]];

console.log(getProducts(specs));

好东西,mark

回到顶部