[javascript] split string in two on given index and return both parts

I have a string that I need to split on a given index and then return both parts, seperated by a comma. For example:

string: 8211 = 8,211
        98700 = 98,700

So I need to be able to split the string on any given index and then return both halves of the string. Built in methods seem to perform the split but only return one part of the split.

string.slice only return extracted part of the string. string.split only allows you to split on character not index string.substring does what I need but only returns the substring string.substr very similar - still only returns the substring

This question is related to javascript

The answer is


Something like this?...

 function stringConverter(varString, varCommaPosition)
 {
   var stringArray = varString.split("");
   var outputString = '';
   for(var i=0;i<stringArray.length;i++)
   {
     if(i == varCommaPosition)
      {
        outputString = outputString + ',';
      }

     outputString = outputString + stringArray[i];
   }  

   return outputString;
 }

You can easily expand it to split on multiple indexes, and to take an array or string

const splitOn = (slicable, ...indices) =>
  [0, ...indices].map((n, i, m) => slicable.slice(n, m[i + 1]));

splitOn('foo', 1);
// ["f", "oo"]

splitOn([1, 2, 3, 4], 2);
// [[1, 2], [3, 4]]

splitOn('fooBAr', 1, 4);
//  ["f", "ooB", "Ar"]

lodash issue tracker: https://github.com/lodash/lodash/issues/3014


You can also do it like this.
https://jsfiddle.net/Devashish2910/8hbosLj3/1/#&togetherjs=iugeGcColp

var str, result;
str = prompt("Enter Any Number");

var valueSplit = function (value, length) {
    if (length < 7) {
        var index = length - 3;
        return str.slice(0, index) + ',' + str.slice(index);
    }
    else if (length < 10 && length > 6) {
        var index1, index2;
        index1 = length - 6;
        index2 = length - 3;
        return str.slice(0,index1) + "," + str.slice(index1,index2) + "," + str.slice(index2);
    }
}

result = valueSplit(str, str.length);
alert(result);

If code elegance ranks higher than the performance hit of regex, then

'1234567'.match(/^(.*)(.{3})/).slice(1).join(',')
=> "1234,567"

There's a lot of room to further modify the regex to be more precise.

If join() doesn't work then you might need to use map with a closure, at which point the other answers here may be less bytes and line noise.


function splitText(value, index) {
  if (value.length < index) {return value;} 
  return [value.substring(0, index)].concat(splitText(value.substring(index), index));
}
console.log(splitText('this is a testing peace of text',10));
// ["this is a ", "testing pe", "ace of tex", "t"] 

For those who want to split a text into array using the index.


You can also use number formatter JS available at

https://code.google.com/p/javascript-number-formatter/

Format options

http://jsfiddle.net/chauhangs/hUE3h/

  format("##,###.", 98700)
  format("#,###.", 8211)

If you want a really hacky one-liner using regular expressions and interpolated strings...

_x000D_
_x000D_
const splitString = (value, idx) => value.split(new RegExp(`(?<=^.{${idx}})`));
console.log(splitString('abcdefgh', 5));
_x000D_
_x000D_
_x000D_

This code says split the string by replacing the value returned in the regex. The regex returns a position, not a character, so we don't lose in characters in the initial string. The way it does this is finding the position, via a look-behind and the ^ anchor, where there were index characters from the start of the string.


To solve your proposed problem of adding commas every third position from the end, the regex would be slightly different and we'd use replace rather than split.

_x000D_
_x000D_
const values = [ 8211, 98700, 1234567890 ];
const addCommas = (value, idx) => value.replace(new RegExp(`(?=(.{${idx}})+$)`, 'g'), ',');

console.log(values.map(v => addCommas(v.toString(), 3)));
_x000D_
_x000D_
_x000D_

Here we find the idxth position from the end by using a look-ahead and the $ anchor, but we also capture any number of those sets of positions from the end. Then we replace the position with a comma. We use the g flag (global) so it replaces every occurrence, not just the first found.


ES6 1-liner

_x000D_
_x000D_
// :: splitAt = number => Array<any>|string => Array<Array<any>|string>_x000D_
const splitAt = index => x => [x.slice(0, index), x.slice(index)]_x000D_
_x000D_
console.log(_x000D_
  splitAt(1)('foo'), // ["f", "oo"]_x000D_
  splitAt(2)([1, 2, 3, 4]) // [[1, 2], [3, 4]]_x000D_
)_x000D_
  
_x000D_
_x000D_
_x000D_