0

I am calling split() on a (dynamic/user input based) string and performing an operation on each element in the returned array. Occasionally I will have a string with only a single character ('/') and this has produced some unexpected results (to me at least).

If I call this:

var randomString = '/';
var splitString = randomString.split('/');

splitString returns a value of ["", ""]. I expected to receive just [""].

Is there a reason I am getting 2 empty strings in the returned array? I couldn't find any documentation or examples of why this is happening. Additionally, if I want to receive just a single empty string in this example, what would be the best way? Just remove the last empty string?

Thanks

biddano
  • 491
  • 5
  • 16
  • 1
    before the / is an empty string, after / is an empty string I guess that's why – EugenSunic Feb 12 '20 at 23:46
  • Yes, split returns an array of 2 element (1 before the split character and 1 after). What are you trying to do here? As in why are you using split? – wakakak Feb 12 '20 at 23:46
  • Same thing happens in Python. You are basically cutting the string in two. Since there is only one element to begin with you get two empty strings. – jws1 Feb 12 '20 at 23:47
  • @GlenK thanks I guess that makes sense. I am taking the window path (window.location.path) and generating a breadcrumb UI. The content itself is dynamic based on the path – biddano Feb 12 '20 at 23:54
  • split(needle) will return one string if needle is not found and each additional string for each needle it finds. So if it finds one needle, it will return 2 strings and 3 strings for 2 needles found and so on. I'm getting what you're trying to accomplish here. Why do you expect to get one empty string? – Ethan Doh Feb 12 '20 at 23:56
  • I suppose you can take use answer by @calarin as it will remove all empty strings. You're at the root path if its length is 0. – Ethan Doh Feb 13 '20 at 00:05

2 Answers2

1

Is there a reason I am getting 2 empty strings in the returned array?

The string is split at '/', so the .split() returns whatever is before and after the '/'.

If the string were var randomString = 'Joe/Bill' then it would return ["Joe", "Bill"].

In your case, there are no characters before or after the split, so you get ["", ""].

As Oussail said, if you then add .filter(Boolean) then it will remove all empty strings, leaving you with an empty array [].

(.filter(Boolean) will remove any empty strings from the array, see here: https://stackoverflow.com/a/54623591/12825520)

You could then check for this with:

var randomString = '/';
var splitString = randomString.split('/');

// Remove any empty strings from the results
splitString = splitString.filter(Boolean);

if (splitString.length === 0) {
   // do something here
   //
   // This might be a special case so you might
   // want to handle it in a specific way
}
calarin
  • 226
  • 1
  • 10
0

To figure out why the method does what it does, a good strategy is to think about how it's implemented.

I don't know the native implementation of the split() method for JS, but it occurs to me that the algorithm traverses the string looking for the passed separator, stores the left portion of the string and then continues until done.

This is a rudimentary version of a split function, with the condition that it matches a single character separator:

    function split(string, separator) {
      let substring = '';
      const results = [];
      // Iterate over the characters of the string
      for (let index = 0; index < string.length; index++) {
        const character = string[index];
        // Check if we found the separator
        if (character === separator) {
          // Save the current stored substring
          results.push(substring);
          // Set the new substring as empty
          substring = '';
        } else {
          // Add the character to the substring
          substring += character;
        }
      }
      results.push(substring);
      return results;
    }

Obviously the String.prototype.split() method is not implemented like this, but I think it should follow the same logic (having care to consider more complex separators, such as words or regexes).

I hope this clarifies why the returned result is 2 empty strings (in your case), because:

  • The substring starts by default as an empty string ("")
  • After finding the separator, the substring (which is an empty string) is saved to the results array and then set to an empty string again.
  • Finally, after checking the whole string (in this case the only 1 character "/"), the remaining substring (also an empty string) is saved to the results.

NOTE: split() is not restricted to a two element array, and potentially can return an array the same length of the original string (for example, when calling it with an empty string separator).