2

I am new to javascript still trying to learn things.
I've found a solution to a problem about a function that should generate all combinations of a characters within a string.

I'm trying to figure out:

  • What is happening inside the loop?
  • How does the loops execute step by step?
    I cannot figure how it reaches to that final output.

I tried for a long time to figure out but I m not sure what happens inside those loops. I don't understand tho how it gets "ab", "ac". ... together in the final output and where arrTemp pushes result[x] and char. I saw that the result array is initially empty, then is concatenated with arrTemp.

Here is the code I'm struggling with:

 function combString(str){
     var lenStr = str.length;
     var result = [];
     var indexCurrent = 0;

     while(indexCurrent < lenStr){
         var char = str.charAt(indexCurrent);
         var x;
         var arrTemp = [char];

         for(x in result) {
             arrTemp.push(""+result[x]+char);
         }
         result = result.concat(arrTemp);

         indexCurrent++;
     }

     return result;
}

console.log(combString("abc"));

And this is the output

["a", "b", "ab", "c", "ac", "bc", "abc"]
Antony
  • 1,253
  • 11
  • 19
Osiris
  • 107
  • 4
  • 14
  • 2
    Step through it. Play computer with paper and pencil. Start with a small input example. There's almost no code here-and developing an ability to understand code in your head is important. – Dave Newton Jan 25 '17 at 18:32
  • Shouldn't you generate the empty string as well? – Willem Van Onsem Jan 25 '17 at 18:33
  • This function doesn't get *every* combination - it leaves out ca, cb, cba, etc. Maybe to help you understand it you could try modifying it to look for those combinations? – raphael75 Jan 25 '17 at 18:39
  • I know it doesn t find all of them but I struggle to find out how hose combinations get into the array especially those like "ab", "ac", "bc", etc. I m not sure how those loops execute tho cause is a loop inside another loop but I guess while executes 2 times then for loop one time then while one more time and 3 times for loop. I see that it concatenates result array which is empty with arrTemp. – Osiris Jan 25 '17 at 18:43

5 Answers5

3

We can simply achieve it by using 'Slice'

function combinator (s) {
   list_of_strings = new Array();
   for(i=0;i<s.length;i++) {
       for(j=i+1;j<s.length+1;j++) {
           list_of_strings.push(s.slice(i, j));
       }
   }
   return list_of_strings;
}

document.write(combinator("dog"));
David Buck
  • 3,752
  • 35
  • 31
  • 35
2

ok that's pretty simple frist I will comment the code for you and then I will show what is done with a simple string example:

function combString(str){
 var lenStr = str.length;
 var result = [];
 var indexCurrent = 0;

 while(indexCurrent < lenStr){ // repeat until indexCurrent equals lenStr, the aim is to browse threw the string
     var char = str.charAt(indexCurrent); // select the char at indexCurrent
     var x;
     var arrTemp = [char];//put the selected char in an array

     for(x in result) {


    /*Here it's a little bit tricky, array are object, and actually
 the indexes of the array are properties which names are includes between 0 and
 2³²-2, but they can have other properties like any other object. that's 
the reason why you can use a for in loop here which will go threw the 
array and perform action on its properties with property name stored in the x variable (actually it is better to use a foreach loop) */


            arrTemp.push(""+result[x]+char); /* so here you concat the 
value of the current property of result (in the for in loop) with the char
 at indexCurrent and you add the concatenation result at the end of arrTemp */
     }
     result = result.concat(arrTemp); //here you concat result array and arrTemp and assign the concatenation result to result (I know there is a lot of result ahah)

     indexCurrent++; //and then you go to the next char in the string and you repeat 
 }
 // when the while loop ends you return result
 return result;

}

so let's see an example with this string "abc":

for indexCurrent =0 :

result = [];
char = 'a';
arrayTemp (before for in loop)= ['a'];
arrayTemp (after for in loop)= ['a'];
result = ['a'];

for indexCurrent =1 :

result = ['a'];
char = 'b';
arrayTemp (before for in loop) = ['b'];
arrayTemp (after for in loop) = ['b','ab']
result = ['a', 'b', 'ab'];

for indexCurrent =2 :

result = ['a', 'b', 'ab'];
char = 'c';
arrayTemp (before for in loop) = ['c'];
arrayTemp (after for in loop) = ['c','ac','bc','abc']
result = ['a', 'b', 'ab','c','ac','bc','abc'];

I hope that helped you

Fanyo SILIADIN
  • 802
  • 5
  • 11
0

Here is the commented code, hopefully it will help you understand!

function combString(str) {
    //String length
    var lenStr = str.length;
    //Initially empty, where the results will be stored
    var result = [];
    //Currently selected letter
    var indexCurrent = 0;

    //Looping from 0 to the length of the string
    //var char is selecting the character at this index. Ex: "a", then "b", then "c"
    while (indexCurrent < lenStr) {
        //Get the character at the index position. 
        var char = str.charAt(indexCurrent);

        var x;
        var arrTemp = [char];
        //For each previous result
        for (x in result) {
            //Add the current character to the index

            arrTemp.push("" + result[x] + char);

            /*
             * Ex: "abc"
             * First round: result is empty, so this code doesn't execute
             * Second round: result contains "a". Adds "ab" to the result array
             *  - Then. result array will contain "a","b" and "ab"
             * Third round: result contains "a","b","ab"
             *     For all of these results, add "c" to the resulting array
             *     Ex: "ac","bc", "abc"
             *  - Then add "c"
             */
        }
        result = result.concat(arrTemp);

        //Increment the current index to go to the next character 
        indexCurrent++;
    }

    return result;
}

console.log(combString("abc"));
Antony
  • 1,253
  • 11
  • 19
  • So arrTemp will contain in its array ["a"] then on the next iteration will add b so ArrTemp=["a","b"] but how it gets a and b together like "ab"? – Osiris Jan 25 '17 at 18:58
  • In the `for (x in result)` section, when the array contains "a" only, it will append "ab" to arrTemp before adding both (b and ab) to the final array. – Antony Jan 25 '17 at 18:59
0

Let's assume input is "ab". Here's how the function works without the loops:

var str = "ab";

var lenStr = str.length;
var result = [];
var indexCurrent = 0;

var char, x, arrTemp;

//first while iteration begins

//indexCurrent === 0
//so char becomes "a"
char = str.charAt(indexCurrent);

//A temp array is created so it can be concatenated to the results array.
arrTemp = [char];
//arrTemp == ["a"]

//for-loop here, but since the result array is empty, it wont execute

//result becomes ["a"]
result = result.concat(arrTemp);

//indexCurrent becomes 1
indexCurrent++;

//second while iteration begins

//indexCurrent === 1
//so char becomes "b"
char = str.charAt(indexCurrent);

arrTemp = [char];
//arrTemp == ["b"]

//For-loop begins, x === 0  
//result[x] is the xth (in this case, first) value of the result-array
//the double quotes cast the result as string  
//in other words, it says:
//"store at the end of the array arrTemp, as string, the value from index x
//in the array result, plus the character stored in the variable char"
arrTemp.push(""+result[x]+char);

//arrTemp is now ["b", "ab"]

//result only has one item, so for-loop ends

//result becomes ["a", "b", "ab"]
result = result.concat(arrTemp);

//indexCurrent becomes 2
indexCurrent++;

//function returns result

Do note that for-in loops should not be used for iterating over arrays (see here).

Community
  • 1
  • 1
Schlaus
  • 18,144
  • 10
  • 36
  • 64
0

Simple use of for loop and while statement to get different combinations.

function combu(s){
var buff = [];
var res = [];
for (i=0;i<s.length;i++){
    buff = [s[i]];
    var index=0;
    while(res[index]){
        buff.push(''+res[index]+s[i]);
        index++;
    }
    res = res.concat(buff);
}
return res;
}

combu('abc');
Sagar Munjal
  • 762
  • 11
  • 12