美文网首页
取出数组中所有排列组合(JS实现)

取出数组中所有排列组合(JS实现)

作者: 银魂飞雪 | 来源:发表于2019-04-11 16:58 被阅读0次

    先定义一个函数,用于从 指定数组 取出 指定数量 的所有排列组合情况。

    原理如下

    1. 先取第一项的所有情况,得到一个数组, 类似[ [1], [2], [3] ]
    2. 递归取出count - 1的所有情况,得到一个数组,类似 [ [a, b], [a,c], [a, d] ]
    3. 把第1步和第2步的两个数组交叉组合,即可得到最终结果

    代码如下

    /**
     * 
     * @param {*} source 源数组
     * @param {*} count 要取出多少项
     * @param {*} isPermutation 是否使用排列的方式
     * @return {any[]} 所有排列组合,格式为 [ [1,2], [1,3]] ...
     */
    function getNumbers(source, count, isPermutation = true) {
      //如果只取一位,返回数组中的所有项,例如 [ [1], [2], [3] ]
      let currentList = source.map((item) => [item]);
      if (count === 1) {
        return currentList;
      }
      let result = [];
      //取出第一项后,再取出后面count - 1 项的排列组合,并把第一项的所有可能(currentList)和 后面count-1项所有可能交叉组合
      for (let i = 0; i < currentList.length; i++) {
        let current = currentList[i];
        //如果是排列的方式,在取count-1时,源数组中排除当前项
        let children = [];
        if (isPermutation) {
          children = getNumbers(source.filter(item => item !== current[0]), count - 1, isPermutation);
        }
        //如果是组合的方法,在取count-1时,源数组只使用当前项之后的
        else {
          children = getNumbers(source.slice(i + 1), count - 1, isPermutation);
        }
        for (let child of children) {
          result.push([...current, ...child]);
        }
      }
      return result;
    }
    
    let arr = [1, 2, 3];
    
    const result = getNumbers(arr, 2, false);
    console.log(result);
    //[ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ] ]
    
    const result2 = getNumbers(arr, 2);
    console.log(result2);
    //[ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ]
    

    一个关键点

    • 如果是排列的方式,后续数组,只要排除当前项即可
      getNumbers(source.filter(item => item !== current[0]), count - 1, isPermutation);

    • 如果是组合方式,后续数组只能当前项之后的值
      getNumbers(source.slice(i + 1), count - 1, isPermutation);

    原因是:
    当第一项为3时,
    如果是排列,那么第二项允许为1;
    如果是组合,则不允许为1——理由:当第一项为1时,已经有过1,3的组合,所以第一项为3,不允许出现3,1的组合

    输出所有排列组合

    循环数组长度,调用上面的函数即可

    let arr = [1, 2, 3];
    
    for (let i = 1; i <= arr.length; i++) {
      console.log(getNumbers(arr, i));
      console.log('\r\n');
    }
    console.log('\r\n--------\r\n');
    
    for (let i = 1; i <= arr.length; i++) {
      console.log(getNumbers(arr, i, false));
      console.log('\r\n');
    }
    
    
    //输出结果如下
    [ [ 1 ], [ 2 ], [ 3 ] ]
    
    [ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 2, 3 ], [ 3, 1 ], [ 3, 2 ] ]
    
    [ [ 1, 2, 3 ],
      [ 1, 3, 2 ],
      [ 2, 1, 3 ],
      [ 2, 3, 1 ],
      [ 3, 1, 2 ],
      [ 3, 2, 1 ] ]
    
    --------
    
    [ [ 1 ], [ 2 ], [ 3 ] ]
    
    [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ] ]
    
    [ [ 1, 2, 3 ] ]
    

    相关文章

      网友评论

          本文标题:取出数组中所有排列组合(JS实现)

          本文链接:https://www.haomeiwen.com/subject/eacxwqtx.html