Given 3 characters (abc
), I want to generate all possible 5-letter strings with them (aaaaa
, aaaab
, … ccccb
, ccccc
)
JavaScript
x
16
16
1
const s = 'byg';
2
const p = [];
3
4
for (let i = 0; i < 3; i++) {
5
for (let j = 0; j < 3; j++) {
6
for (let k = 0; k < 3; k++) {
7
for (let l = 0; l < 3; l++) {
8
for (let m = 0; m < 3; m++) {
9
p.push(s[i] + s[j] + s[k] + s[l] + s[m]);
10
}
11
}
12
}
13
}
14
}
15
16
console.log(p, p.length === 3 ** 5)
This feels like an inefficient way to do this, so is there a more elegant/efficient way to do this?
Advertisement
Answer
Your nested for loops does imply that code can be refactored either using recursion or as in my example below by creating a higher level loop.
This approach allows us to generate strings of any desired length.
JavaScript
1
25
25
1
let characters = "abc";
2
let desiredLength = 5;
3
4
let theSet = [""];
5
for ( let length = 0; length < desiredLength; length++){
6
let extendedSet = [];
7
theSet.forEach( (item) =>
8
extendedSet.push( extendWith( item, characters) )
9
)
10
theSet = extendedSet;
11
}
12
13
console.log('result ', theSet);
14
15
// given a strings and a set of characters
16
// generate an array of string extended with each
17
// of the characters.
18
// "a" with "xy" generates
19
// [ "ax", "ay" ]
20
function extendWith( extendThis, characters){
21
let result = [];
22
[characters].forEach( (c) => result.push(extendThis+c) );
23
return result;
24
}
25
We can make that extendWith function more succinct like this
JavaScript
1
4
1
function extendWith( extendThis, characters){
2
return [characters].map( c => extendThis + c );
3
}
4
and as it’s now just a one line expression we can dispense with the utility function and simplify a bit more
JavaScript
1
8
1
for ( let length = 0; length < desiredLength; length++){
2
3
theSet = theSet.flatMap( (item) =>
4
[characters].map( c => item + c )
5
);
6
7
}
8