3

I have a string that I need to split by a certain delimiter and convert into an array, but without removing the delimiter itself. For example, consider the following code:

var str = "#mavic#phantom#spark";
str.split("#") //["", "mavic", "phantom", "spark"]

I need the output to be as follows:

["#mavic", "#phantom", "#spark"]

I read here but that does not answer my question.

Alex
  • 1,982
  • 4
  • 37
  • 70

4 Answers4

8

You could split by positive lookahead of #.

var string = "#mavic#phantom#spark",
    splitted = string.split(/(?=#)/);

console.log(splitted);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Regular expressions are awesome. I like using [regex101.com](https://regex101.com/r/TAkEk0/1) to test them out (still learning!) – random_user_name Aug 26 '18 at 16:06
  • Awesome. Exactly what I needed, interestingly never heard of "positive lookahead". Many thanks. – Alex Aug 26 '18 at 16:07
  • Important point here is that the separator can be either a string or regular expression. [String.prototype.split() MDN doc for reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split#Parameters) – stealththeninja Aug 26 '18 at 16:07
1

Split the string by # and use the reduce to return the modified string

var str = "#mavic#phantom#spark";
let x = str.split("#").reduce((acc, curr) => {
  if (curr !== '') {
    acc.push('#' + curr);
  }
  return acc;
}, [])
console.log(x)
brk
  • 48,835
  • 10
  • 56
  • 78
0

Here is also some non-regexp methods of solving your task:

Solution 1 classical approach - iterate over the string and each time when we find indexOf our delimiter, we push to the result array the substring between current position and the next position. In the else block we have a case for the last substring - we simply add it to the result array and break the loop.

const delimiter = '#';
const result1 = [];
let i = 0;
while (i < str.length) {
  const nextPosition = str.indexOf(delimiter, i+1);
  if (nextPosition > 0) {
    result1.push(str.substring(i, nextPosition));
    i = nextPosition;
  } else {
    result1.push(str.substring(i));
    break;
  }
}

Solution 2 - split the initial string starting at index 1 (in order to not include empty string in the result array) and then just map the result array by concatenating the delimiter and current array item.

const result2 = str.substr(1).split(delimiter).map(s => delimiter + s);
shohrukh
  • 2,989
  • 3
  • 23
  • 38
0

another way: filter empty elements after splitting, and map these elements to start with the character you splitted with.

string.split("#").filter((elem) => elem).map((elem) => "#" + elem);
Lihai
  • 323
  • 2
  • 6
  • 18