Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I am looking for a review of my recursive function that generates the permutations of a string. Are there better ways to do this?

var permutations = [];

function doPerm(str, arr) {
    if (typeof (str) == 'string') str = str.split('');
    if (str.length == 0) permutations.push(arr.join(''));
    for (var i = 0; i < str.length; i++) {
        var x = str.splice(i, 1);
        arr.push(x);
        doPerm(str, arr);
        arr.pop();
        str.splice(i, 0, x);
    }
}
doPerm('', []);
console.log(permutations);
share|improve this question
1  
good code , no improvement needed as per this context –  paritosh Aug 10 at 9:57
    
An implementation of Heap's algorithm in JavaScript (mentioned in @amon's answer) can be found here. –  mjolka Aug 10 at 13:00
    
FYI, typeof is an operator, not a function. The parentheses around str are unnecessary and misleading. –  Ingo Bürk Aug 10 at 13:55

1 Answer 1

up vote 3 down vote accepted

Your code seems to be correct, and is written in a good style. However, both the interface of your code as well as the algorithm used can be improved.

You currently have a global variable permutations which also contains the output. This variable will have to be cleared every time before doPerm is invoked. Instead, wrap doPerm in another function that provides initialization and input validation:

function perms(data) {
    if (!(data instanceof Array)) {
        throw new TypeError("input data must be an Array");
    }

    data = data.slice();  // make a copy
    var permutations = [],
        stack = [];

    function doPerm() {
        if (data.length == 0) {
            permutations.push(stack.slice());
        }
        for (var i = 0; i < data.length; i++) {
            var x = data.splice(i, 1);
            stack.push(x);
            doPerm();
            stack.pop();
            data.splice(i, 0, x);
        }
    }

    doPerm();
    return permutations;
}

var input = "abcd".split('');
var result = perms(input);
for (var i = 0; i < result.length; i++) {
    result[i] = result[i].join('');
}
console.log(result);

Note that this function will operate on arrays of any type and does not special-case strings.

Your algorithm currently relies on splicing elements into and out of the input array. This is somewhat expensive on larger data sets, and it would be better to generate the permutations by swapping. Heap's Algorithm does just this.

share|improve this answer
1  
Nice, although I'd recommend throwing a TypeError instead –  Flambino Aug 10 at 11:06
3  
I think perms and doPerm are horrible names. Why not choose something meaningful? –  Ingo Bürk Aug 10 at 13:55
1  
@IngoBürk quite right, doPerm could be improved – I'd probably use _perms or recurse in my own code. However, I do not see anything wrong with the name perms for a function that calculates permutations. There's a balance to be found between explicitness and terseness, and I think perms is a name that strikes a good balance when used for a local variable or method name. –  amon Aug 10 at 14:29
1  
@amon Personally, I tend to be descriptive, so I'd probably write something like calculatePermutations. But even if one doesn't want to do that, I think abbreviating is unnecessary here. permutations would be simple and short, but expressive. I like recurse for the inner function's name. –  Ingo Bürk Aug 10 at 15:06
    
great review, but why not replacing if (!(data instanceof Array)) { with if (!Array.isArray(data)) {? –  renatoargh Aug 10 at 19:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.