今天在做商品规格属性时需要写一个排列组合算法,请大佬帮忙看看

代码牛
  • 1.5k

排列组合

let formats = [
    [
        {id: 1,name:'红色'},
        {id: 2,name:'白色'}
    ],
    [
        {id: 1,name:'100*200'},
        {id: 2,name:'50*200'}
    ],
    [
        {id: 1,name:'20厘米'},
        {id: 2,name:'10厘米'}
    ]
]

输出结果:

let result = [
    [
        {id: 1,name:'红色'},
        {id: 1,name:'100*200'},
        {id: 1,name:'20厘米'}
    ],
    [
        {id: 1,name:'红色'},
        {id: 2,name:'50*200'
        },
        {id: 1,name:'20厘米'}
    ],
    [
        {id: 1,name:'红色'},
        {id: 2,name:'50*200'},
        {id: 2,name:'10厘米'}
    ]
]

简化说明:

[[1,2][3,4][5,6]]
排列组合算法得到=》
[
    [1,3,5],
    [1,3,6],
    [1,4,5],
    [1,4,6],
    [2,3,5],
    [2,3,6],
    [2,4,5],
    [2,4,6]
]
回复
阅读 1.9k
4 个回答
const dealTwo = (arr1, arr2) => {
    let result = [];
    arr1.forEach(val1 => {
        arr2.forEach(val2 => {
            if (typeof val1 === 'number') {
                result.push([val1, val2]);
            } else {
                result.push(val1.concat(val2));
            }
        })
    })
    return result;
}
const permutation = (arr) => {
    const len = arr.length;
    if (len <= 1) {
        return arr;
    }
    let result = arr[0];
    for (let i = 1; i < len; i++) {
        result = dealTwo(result, arr[i]);
    }
    return result;
}
console.log(permutation([[1, 2], [3, 4], [5, 6]]));

思路就是2个2个的进行遍历合并

let mix = (function(){

    function _mix()
    {
        let arrMix = [];

        if(arguments.length > 0)
        {
            let arrArg = Array.prototype.slice.call(arguments);
            let arg = arrArg.shift();

            let arr = _mix.apply(null, arrArg);
            if(Array.isArray(arg) === true)
            {
                for(let i=0; i<arg.length; i++)
                {
                    for(let j=0; j<arr.length; j++)
                    {
                        arrMix.push([arg[i]].concat(arr[j]));
                    }
                }

            }
            else
            {
                for(let j=0; j<arr.length; j++)
                {
                    arrMix.push([arg].concat(arr[j]));
                }
            }
        }
        else
        {
            arrMix.push([]);
        }

        return arrMix;
    }

    return function($arr){
        return _mix.apply(null, $arr);
    };

})();

console.log(mix([[1,2],[3,4],[5,6]]));
console.log(mix([1,2,[3,4]]));

抄的,稍微做了一点改动,动用了全局变量,不太好,其实最好还是在递归中传参数,至少功能实现了。
原文地址:https://www.cnblogs.com/linJi...

function doExchange(arr, depth)
{
    for (var i = 0; i < arr[depth].length; i++) {
        result[depth] = arr[depth][i]
        if (depth != arr.length - 1) {
            doExchange(arr, depth + 1)
        } else {
            results.push(JSON.parse(JSON.stringify( result)));
        }
    }
}

function test(arr)
{
    results = [];
    result = [];
    doExchange(arr, 0);
    console.log(results.length, results);
}
garr = [
['a', 'b', 'c'],
['1', '2', '3'],
['x', 'y', 'z'],
]
test(garr)

刚刚看错题目,尴尬~~~


这个问题递归好解决,将问题分割为每次只求两项的笛卡儿积,然后依赖递归求到最终结果即可。
代码:

function combination(list, lastResult = []) {
  if (!list.length) return lastResult
  let subList = list.shift()
  if (!subList.length) return lastResult
  if (!lastResult.length) {
    return combination(list, subList.map(item => [item]))
  }
  
  let result = []
  for (let res of lastResult) {
    for (let item of subList) {
      result.push([...res, item])
    }
  }
  return combination(list, result)
} 

调用:

console.log(JSON.stringify(combination(formats)))

输出:

[
    [
        {
            "id":1,
            "name":"红色"
        },
        {
            "id":1,
            "name":"100*200"
        },
        {
            "id":1,
            "name":"20厘米"
        }
    ],
    [
        {
            "id":1,
            "name":"红色"
        },
        {
            "id":1,
            "name":"100*200"
        },
        {
            "id":2,
            "name":"10厘米"
        }
    ],
    [
        {
            "id":1,
            "name":"红色"
        },
        {
            "id":2,
            "name":"50*200"
        },
        {
            "id":1,
            "name":"20厘米"
        }
    ],
    [
        {
            "id":1,
            "name":"红色"
        },
        {
            "id":2,
            "name":"50*200"
        },
        {
            "id":2,
            "name":"10厘米"
        }
    ],
    [
        {
            "id":2,
            "name":"白色"
        },
        {
            "id":1,
            "name":"100*200"
        },
        {
            "id":1,
            "name":"20厘米"
        }
    ],
    [
        {
            "id":2,
            "name":"白色"
        },
        {
            "id":1,
            "name":"100*200"
        },
        {
            "id":2,
            "name":"10厘米"
        }
    ],
    [
        {
            "id":2,
            "name":"白色"
        },
        {
            "id":2,
            "name":"50*200"
        },
        {
            "id":1,
            "name":"20厘米"
        }
    ],
    [
        {
            "id":2,
            "name":"白色"
        },
        {
            "id":2,
            "name":"50*200"
        },
        {
            "id":2,
            "name":"10厘米"
        }
    ]
]
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏