I\'m trying to create a function in JavaScript that given a string will return an array of all possible combinations of the letters with each used at most once, starting wit
You could use a nasty trick and increase a counter and use its binary representation as flags:
function combine(str){
const result = [];
for(let i = 1; i < Math.pow(2, str.length) - 1; i++)
result.push([...str].filter((_, pos) => (i >> pos) & 1).join(""));
return result;
}
Try it
This is what I ended up using.
var combinations = function (string)
{
var result = [];
var loop = function (start,depth,prefix)
{
for(var i=start; i<string.length; i++)
{
var next = prefix+string[i];
if (depth > 0)
loop(i+1,depth-1,next);
else
result.push(next);
}
}
for(var i=0; i<string.length; i++)
{
loop(0,i,'');
}
return result;
}
You couldm take an iterative and recursive approach by using the character at the given key or not.
function combine(string) {
function iter(i, temp) {
if (i >= string.length) {
result.push(temp);
return;
}
iter(i + 1, temp + string[i]);
iter(i + 1, temp);
}
var result = [];
iter(0, '');
return result;
}
console.log(combine('jump'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Generators allow a very clean implementation:
// Very short generator produces all possible strings composed of the given chars!
let allStrings = function*(chars) {
yield '';
for (let prefix of allStrings(chars)) for (let c of chars) yield `${prefix}${c}`;
};
// Render the first 1000 strings
document.body.style.fontFamily = 'monospace';
let count = 0;
for (let str of allStrings('abcd')) {
let div = document.createElement('div');
div.innerHTML = `${(count + 1).toString().padStart(4, '0')}: ${str}`;
document.body.appendChild(div);
if (count++ > 1000) break;
}
Note that the very first result from allStrings
is the empty string. If it's crucial to avoid this the following implementation can be used:
let allStrings = function*(chars, includeEmpty=false) {
if (includeEmpty) yield '';
for (let prefix of allStrings(chars, true)) for (let c of chars) yield `${prefix}${c}`;
};
function combinations(var1) {
var temp;
for (var i = 0; i < var1.length; i++) {
var2 = "";
temp = i;
while (temp < var1.length) {
var2 = var2.concat(var1.charAt(temp));
// console.log(var2)
if (i == var1.length - 1)
document.getElementById('result').innerHTML += var2;
else
document.getElementById('result').innerHTML += var2 + ',';
temp++;
}
}
}
This is a recursive solution that I think is very easy to understand.
var tree = function(leafs) {
var branches = [];
if (leafs.length == 1) return leafs;
for (var k in leafs) {
var leaf = leafs[k];
tree(leafs.join('').replace(leaf, '').split('')).concat("").map(function(subtree) {
branches.push([leaf].concat(subtree));
});
}
return branches;
};
console.log(tree("abc".split('')).map(function(str) {
return str.join('')
}))