Reputation: 745
Is there a javascript/jquery method or function that will let me split a string at nth occurrence of a selected delimiter? I'd like it work just like the regular str.split(delimiter) except instead of splitting at every occurrence of the delimiter it could be instructed to skip n number of them each time.
var str = "A,BB,C,DDD,EEEE,F";
var strAry = str.split(",");
Would result in strAry looking like {"A","BB","C","DDD","EEEE","F"}
What I want would be {"A,BB","C,DDD","EEEE,F"} assuming I set nth occurance to 2.
I wrote a small function that appears to work but hoping there was a simpler way to do this:
function splitn(fullString, delimiter, n){
var fullArray = fullString.split(delimiter);
var newArray = [];
var elementStr = "";
for(var i = 0; i < fullArray.length; i++) {
if (i == fullArray.length-1) {
if (elementStr.length == 0) {
elementStr = fullArray[i];
} else {
elementStr += (delimiter + fullArray[i]);
}
newArray.push(elementStr);
} else {
if (((i + 1) % n) == 0) {
if (elementStr.length == 0) {
elementStr = fullArray[i];
} else {
elementStr += (delimiter + fullArray[i]);
}
newArray.push(elementStr);
elementStr = "";
} else {
if (elementStr.length == 0) {
elementStr = fullArray[i];
} else {
elementStr += (delimiter + fullArray[i]);
}
}
}
};
return newArray;
};
Thanks.
Upvotes: 1
Views: 638
Reputation:
EDIT: Just noticed you wanted to use an arbitrary "nth" value. I updated it so you can simply change the nth
to whatever positive integer you like.
Here's a way that takes advantage of the second argument to .indexOf()
so that you can anchor your searches from after the last ending point in the string:
function splitn(fullString, delimiter, n) {
var lastIdx = 0
, idx = -1
, nth = 0
, result = [];
while ((idx = fullString.indexOf(delimiter, idx + delimiter.length)) !== -1) {
if ((nth = ++nth % n) === 0) {
result.push(fullString.slice(lastIdx, idx));
lastIdx = idx + 1;
}
}
result.push(fullString.slice(lastIdx));
return result;
}
var result = splitn("A,BB,C,DDD,EEEE,F", ",", 2);
document.body.innerHTML = "<pre>" + JSON.stringify(result, null, 4) + "</pre>";
Upvotes: 1
Reputation: 25310
You could simply use Array.prototype.reduce() to modify the array returned by split to your liking. The idea is similar to your code, just shorter.
function modify(str, n, delim) {
return str.split(delim).reduce(function(output, item, i) {
if (!(i % n)) {
output.push(item);
} else {
output[i / n | 0] += delim + item;
};
return output;
}, []);
};
modify("A,BB,C,DDD,EEEE,F", 3, ','); //["A,BB,C", "DDD,EEEE,F"]
modify("A,BB,C,DDD,EEEE,F", 2, ','); //["A,BB", "C,DDD", "EEEE,F"]
Upvotes: 2