-1

I was trying to solve this codewars question called "Your order, please". Our task is to to sort a given string. Each word in the string will contain a single number. This number is the position the word should have in the result.

Lets say given string is "is2 Thi1s T4est 3a" then expected result is "Thi1s is2 3a T4est".

So here is my code

let words = "is2 Thi1s T4est 3a";
let wordsArr = words.split(" ");
let result = [];
let r = /\d+/g;
let j = 1;



for (let i = 0; i < wordsArr.length; i++) {
  if (wordsArr[i].match(r) == j) {
    result.push(wordsArr[i]);
    j++;
    i = 0;
  }
}

console.log(result.join(""));

It only returns Thi1s.

I tried to write down the iterations of how I think it would work with this for loop.

  1. iteration (i=0, j=1)

    • 2==1? no then i++
  2. iteration (i=1,j=1)

    • 1==1? yes then push.result, j++, i=0
      • result=[Thi1s]
  3. iteration (i=0,j=2)

    • 2==2? yes then push.result, j++, i=0
      • result=[Thi1s, is2]
  4. iteration (i=0,j=3)

    • 2==3? no then i++;
  5. iteration (i=1,j=3)

    • 1==3? no then i++
  6. iteration (i=2,j=3)

    • 4==3? no then i++
  7. iteration (i=3, j=3)

    • 3==3? yes then push.result, j++ i=0
      • result=[Thi1s, is2, 3a]
  8. iteration (i=0,j=4)

    • 2==4? no then i++;
  9. iteration (i=1,j=4)

    • 1==4? no then i++;
  10. iteration (i=2,j=4)

    • 4==4? yes then push.result, j++ i=0
      • result=[Thi1s, is2, 3a, T4est]

Why is it not working the way I expected to work?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 2
    Try doing a console log of `wordsArr[i].match(r)` - I don't think it returns what you're expecting. – LaytonGB Jun 22 '21 at 08:17
  • 1
    `i` will be incremented _after_ the body of the loop has been processed. – Andreas Jun 22 '21 at 08:17
  • 3
    `.match()` returns an array where the first item is your whole match. So `"is2".match(r)` returns `["2"]` – VLAZ Jun 22 '21 at 08:17
  • 1
    Read the [docs](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) and see [How to compare arrays in JavaScript?](/q/7837456/4642212). – Sebastian Simon Jun 22 '21 at 08:22
  • so `wordsArr[0].match(r)=2`, `wordsArr[1].match(r)=1` ,`wordsArr[2].match(r)=4`, `wordsArr[3].match(r)=3` I know that and if they match with the j value they get pushed into the result array. no? – Ömer Faruk Çalışkan Jun 22 '21 at 08:26
  • 1
    @VLAZ The match only contains one element, which is then cast to a string, hence the comparison works (although only because of `==`). OP only has to set `i = -1` in the `if`: https://jsfiddle.net/ubes46kv/ – Andreas Jun 22 '21 at 08:28
  • @Andreas thank you. `i=-1` fixed the issue. I figured out what `i=0` was doing too late :) – Ömer Faruk Çalışkan Jun 22 '21 at 08:39
  • 1
    @ÖmerFarukÇalışkan But as I said. This is only out of pure luck because of the chosen operator (`==`). The points mentioned by VLAZ and LaytonGB are still valid and should not be ignored. – Andreas Jun 22 '21 at 08:40
  • @Andreas But I knew that match was going to return only the integer value inside the strings that was my goal so I could compare with the `j` value easier. Opposite of what LaytonGB said, I knew what it was going to return thats why I used it. Is my approach bad ? – Ömer Faruk Çalışkan Jun 22 '21 at 08:51
  • 1
    Your approach only works because of the implicit conversion of the operands in the `if` condition into strings, and because the matches only contain one element only. If you know these limitations or rather how it works (internally) then go with it. But this isn't fail-proof. – Andreas Jun 22 '21 at 09:37

1 Answers1

1

let words = "is2 Thi1s T4est 3a";
let wordsArr = words.split(" ");
let result = [];
let r = /\d+/g;

outerLoop: // this is a "label" which we can use to reference this for loop
for (let i = 1; i <= wordsArr.length; i++) { // loop 1 to 4, same as the numbers in text
  innerLoop:
  for (let word of wordsArr) { // for each word
    let match = word.match(r); // get the match result
    if (match && match[0] == i) { // if match found, and the part that matches is our next i
      result.push(word); // add word to array
      continue outerLoop; // go to next i
    }
  }
}

console.log(result.join(" "));
LaytonGB
  • 1,384
  • 1
  • 6
  • 20