0

I need to make a function that will sort a string. Each word in the String will contain a single number. Numbers can be from 1 to 9(no 0).

For example an input: "is2 Thi1s T4est 3a" the function should return "Thi1s is2 3a T4est".

My code is :

 function order(words)
 {
 // ... 

    if(words == '')
    {
      return words;
    }

    var all_words = words.split(" ");
    var checked_words = new Array(); 
    var joined_words = "";

    for(i = 1; i <= 9; i++)
    {
      //console.log(checked_words);
      //checked_words[i-1] = all_words;
      for(j = 1;j <= all_words.length; j++)
      {
        if(all_words[i-1].indexOf(i) != -1)
        {
          checked_words.push(all_words[i-1]);

          if(i == (all_words.length))
          {
            joined_words = checked_words.join(" ");
            return joined_words;
          }
        }
      }
    }
  }

The problem is it kept showing "TypeError: Cannot call method 'indexOf' of undefined at order". Please help thanks!

wendy
  • 161
  • 3
  • 14

1 Answers1

2

I've been trying to figure out what that first loop is doing and I finally realised it's checking for the numbers in the string. You shouldn't do it that way because it's 1) weird, 2) non-peformant if it worked.

Instead use one loop and a regex to find the number in the string.

for (var i = 0; i < all_words.length; i++) {

  // take the first match and coerce it to an integer
  var n = +all_words[i].match(/\d+/)[0];
  checked_words[n] = all_words[i];
}

// checked_words has an undefined element at index 0;
// slice takes a copy of the array from index 1
return checked_words.slice(1).join(' ');

DEMO

Alternatively you could use reduce.

var joined_words = str.split(' ').reduce(function (p, c) {
  var n = +c.match(/\d+/)[0];
  p[n] = c;
  return p;
}, []).slice(1).join(' ');

DEMO

You're not even tied to the numbers 0-9. As long as you filter out the undefined elements, you're golden...

var str = 'is2 Thi1s T4est 3a Ye12s!';

var out = str.split(' ').reduce(function (p, c) {
  var n = +c.match(/\d+/)[0];
  p[n] = c;
  return p;
}, []).slice(1).filter(function (el) {
  return el !== undefined;
}).join(' ');

DEMO

Andy
  • 61,948
  • 13
  • 68
  • 95