Permutations in JavaScript?

前端 未结 30 2690
不思量自难忘°
不思量自难忘° 2020-11-21 06:52

I\'m trying to write a function that does the following:

  • takes an array of integers as an argument (e.g. [1,2,3,4])
  • creates an array of all the possib
相关标签:
30条回答
  • 2020-11-21 07:07

    Little late, but like to add a slightly more elegant version here. Can be any array...

    function permutator(inputArr) {
      var results = [];
    
      function permute(arr, memo) {
        var cur, memo = memo || [];
    
        for (var i = 0; i < arr.length; i++) {
          cur = arr.splice(i, 1);
          if (arr.length === 0) {
            results.push(memo.concat(cur));
          }
          permute(arr.slice(), memo.concat(cur));
          arr.splice(i, 0, cur[0]);
        }
    
        return results;
      }
    
      return permute(inputArr);
    }
    

    Adding an ES6 (2015) version. Also does not mutate the original input array. Works in the console in Chrome...

    const permutator = (inputArr) => {
      let result = [];
    
      const permute = (arr, m = []) => {
        if (arr.length === 0) {
          result.push(m)
        } else {
          for (let i = 0; i < arr.length; i++) {
            let curr = arr.slice();
            let next = curr.splice(i, 1);
            permute(curr.slice(), m.concat(next))
         }
       }
     }
    
     permute(inputArr)
    
     return result;
    }
    

    So...

    permutator(['c','a','t']);
    

    Yields...

    [ [ 'c', 'a', 't' ],
      [ 'c', 't', 'a' ],
      [ 'a', 'c', 't' ],
      [ 'a', 't', 'c' ],
      [ 't', 'c', 'a' ],
      [ 't', 'a', 'c' ] ]
    

    And...

    permutator([1,2,3]);
    

    Yields...

    [ [ 1, 2, 3 ],
      [ 1, 3, 2 ],
      [ 2, 1, 3 ],
      [ 2, 3, 1 ],
      [ 3, 1, 2 ],
      [ 3, 2, 1 ] ]
    
    0 讨论(0)
  • 2020-11-21 07:07
    perm = x => x[0] ?  x.reduce((a, n) => (perm(x.filter(m => m!=n)).forEach(y => a.push([n,...y])), a), []): [[]]
    
    0 讨论(0)
  • 2020-11-21 07:08
    #!/usr/bin/env node
    "use strict";
    
    function perm(arr) {
        if(arr.length<2) return [arr];
        var res = [];
        arr.forEach(function(x, i) {
            perm(arr.slice(0,i).concat(arr.slice(i+1))).forEach(function(a) {
                res.push([x].concat(a));
            });
        });
        return res;
    }
    
    console.log(perm([1,2,3,4]));
    
    0 讨论(0)
  • 2020-11-21 07:08

    Similar in spirit to the Haskell-style solution by @crl, but working with reduce:

    function permutations( base ) {
      if (base.length == 0) return [[]]
      return permutations( base.slice(1) ).reduce( function(acc,perm) {
        return acc.concat( base.map( function(e,pos) {
          var new_perm = perm.slice()
          new_perm.splice(pos,0,base[0])
          return new_perm
        }))
      },[])    
    }
    
    0 讨论(0)
  • 2020-11-21 07:10

    Functional answer using flatMap:

    const getPermutationsFor = (arr, permutation = []) =>
      arr.length === 0
        ? [permutation]
        : arr.flatMap((item, i, arr) =>
            getPermutationsFor(
              arr.filter((_,j) => j !== i),
              [...permutation, item]
            )
          );
    
    0 讨论(0)
  • 2020-11-21 07:11

    Here's a cool solution

    const rotations = ([l, ...ls], right=[]) =>
      l ? [[l, ...ls, ...right], ...rotations(ls, [...right, l])] : []
    
    const permutations = ([x, ...xs]) =>
      x ? permutations(xs).flatMap((p) => rotations([x, ...p])) : [[]]
      
    console.log(permutations("cat"))

    0 讨论(0)
提交回复
热议问题