Angel Politis Angel Politis - 2 months ago 13
Javascript Question

Recursive function returns empty array

I have created the following function that aims to split a string to the points requested and returning an array of the words that occurred.

Currently, the function works as it has to, when the arguments are passed one after another, but not when passed inside an array and I want to cover both options.

I have attempted to force the function to rerun itself, if the argument is found to be an array (line 15), but after it runs for a second time the returned array is empty.

Question:

How can fix my code so that the function works properly even when the arguments are passed inside an array?

Code:



function string(str) {
/* Throw error if 'string' is not a string */
if (str.constructor !== String) throw new Error("Argument is not a string.");
else return {
splitAt: function() {
var
args = arguments,
len = args.length,
arg = args[0],
index = 0,
prev = 0,
arr = [];

/* If the indices are passed in an array ([4, 5, 8, 12]) rerun the function */
if (args[0].constructor === Array) string(str).splitAt.apply(this, args[0]);
else for (; index < len; index++, arg = args[index], prev = args[index - 1]) {
/* The first time cut the string at the requested point and save both parts */
if (!index) {
arr[index] = str.substr(0, arg);
arr[index + 1] = str.substr(arg);

/* From then on overwrite the last element of the array */
} else {
arr[index + 1] = arr[index].substr(arg - prev);
arr[index] = arr[index].substr(0, arg - prev);
}
}
return arr;
}
}
}

/* Arguments passed one after another */
console.log(string("Whatadayit'sbeen!").splitAt(4, 5, 8, 12));

/* Arguments passed in an array */
console.log(string("Whatadayit'sbeen!").splitAt([4, 5, 8, 12]));




Answer

I think you missed a return here:

function string(str) {
  /* Throw error if 'string' is not a string */
  if (str.constructor !== String) throw new Error("Argument is not a string.");
  else return {
    splitAt: function() {
      var
        args = arguments,
        len = args.length,
        arg = args[0],
        index = 0,
        prev = 0,
        arr = [];

      /* If the indices are passed in an array ([4, 5, 8, 12]) rerun the function */
      if (args[0].constructor === Array) 
        return string(str).splitAt.apply(this, args[0]);
      else for (; index < len; index++, arg = args[index], prev = args[index - 1]) {
        /* The first time cut the string at the requested point and save both parts */
        if (!index) {
          arr[index] = str.substr(0, arg);
          arr[index + 1] = str.substr(arg);

        /* From then on overwrite the last element of the array */
        } else {
          arr[index + 1] = arr[index].substr(arg - prev);
          arr[index] = arr[index].substr(0, arg - prev);
        }
      }
      return arr;
    }
  }
}

/* Arguments passed one after another */
console.log(string("Whatadayit'sbeen!").splitAt(4, 5, 8, 12));
debugger;
/* Arguments passed in an array */
console.log(string("Whatadayit'sbeen!").splitAt([4, 5, 8, 12]));