Get an array of strings separating a string on N character incrementally
Which makes me wonder, is there a better way to do this without
  recursion, but just as succinctly?


Recursion can be an issue if your input size is huge and you recurse often and your JavaScript engine can't perform tail call optimization. Due to limited call stack size, you might then encounter a Maximum call stack size exceeded error. You might also want to avoid recursion if performance is a concern, as the function call overhead is not marginal in JavaScript.

So, how do you eliminate the recursion?

First of all, in order to gain a clear understanding of Redu's minified one-liner:

res = s =&gt; s.length ? [s].concat(res(s.match(/.*(?=\/.+$)/)[0])) : [];


I recommend to rewrite it into a self-documenting but otherwise equivalent function:

function expand(path) {
  if (path.length == 0) return [];
  let result = [path];

  path = path.match(/.*(?=\/.+$)/)[0];
  result = result.concat(expand(path));

  return result;
}


Now, we can analyze how that function works:


It appends the current path to the result
It replaces the current path with the parent path
It recurses to find a solution for the parent path
It appends the complete path to the solution for the parent path


It is always possible to turn a recursive function into a non-recursive function. We just need to manually keep track of already found paths and the current parent path:



function expand(path) {  
  let result = [];
  
  while (path.length &gt; 0) {
    result.push(path);
    path = path.match(/.*(?=\/.+$)/)[0];
  }
  return result;
}

console.log(expand("/bob/ross/is/awesome/squirrels"));




This non-recursive solution works as-is for empty strings without having to check for this base case. 

We could even minify it again, which I don't recommend:

const res=(s,r=[s])=&gt;{while(s.length)r.push(s=s.match(/.*(?=\/.+$)/)[0]);return r};


In a practical setting, I would recommend a more generative and more robust approach which, in a first step, extracts all valid path segments from the input. In a second step, you would then build the cumulative paths from those segments.

Using Array.map():


function expand(path, prefix = '') {
  return path.match(/[^\/]+/g).map((segment) =&gt; 
    prefix += '/' + segment
  ).reverse();
}

console.log(expand("/bob/ross/is/awesome/squirrels"));




Using Array.reduce():



function expand(path, prefix = '') {
  return path.match(/[^\/]+/g).reduce((path, segment) =&gt; {
    prefix += '/' + segment;
    path.unshift(prefix);
    return path;
  }, []);
}

console.log(expand("/bob/ross/is/awesome/squirrels"));