Skip to content

Commit d61b58f

Browse files
Added splitLeft and splitRight
1 parent c044d6d commit d61b58f

File tree

5 files changed

+212
-14
lines changed

5 files changed

+212
-14
lines changed

README.md

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ Example:
515515
var stuff = "My name is JP\nJavaScript is my fav language\r\nWhat is your fav language?"
516516
var lines = S(stuff).lines()
517517

518-
console.dir(lines)
518+
console.dir(lines)
519519
/*
520520
[ 'My name is JP',
521521
'JavaScript is my fav language',
@@ -526,7 +526,7 @@ console.dir(lines)
526526

527527
### - pad(len, [char])
528528

529-
Pads the string in the center with specified character. `char` may be a string or a number, defaults is a space.
529+
Pads the string in the center with specified character. `char` may be a string or a number, defaults is a space.
530530

531531
Example:
532532

@@ -682,15 +682,43 @@ S('Crème brûlée').slugify().s // 'creme-brulee'
682682
```
683683

684684

685-
### - startsWith(prefix) ###
685+
### - splitLeft(sep, [maxSplit = -1, [limit]]) ###
686+
687+
Returns an array of strings, split from the left at `sep`. Performs at most `maxSplit` splits, and slices the result into an array with at most `limit` elements.
688+
689+
Example:
690+
691+
```javascript
692+
S('We built this city').splitLeft(' '); // ['We', 'built', 'this', 'city'];
693+
S('We built this city').splitLeft(' ', 1); // ['We', 'built this city'];
694+
S('On Rock N Roll and other Stuff').splitLeft(' ', -1, 4); // ['On', 'Rock', 'N', 'Roll'];
695+
S('On Rock N Roll and other Stuff').splitLeft(' ', 5, -2); // ['and', 'other Stuff'];
696+
```
697+
698+
699+
### - splitRight(sep, [maxSplit = -1, [limit]]) ###
700+
701+
Returns an array of strings, split from the left at `sep`. Performs at most `maxSplit` splits, and slices the result into an array with at most `limit` elements.
702+
703+
Example:
704+
705+
```javascript
706+
S('This is all very fun').splitRight(' '); // ['THis', 'built', 'this', 'city'];
707+
S('and I could do it forever').splitRight(' ', 1); // ['and I could do it', 'forever'];
708+
S('but nothing matters in the end.').splitRight(' ', -1, 2); // ['the', 'end.'];
709+
S('but nothing matters in the end.').splitRight(' ', 4, -2); // ['but nothing', 'matters'];
710+
```
711+
712+
713+
### - startsWith(prefix) ###
686714

687715
Return true if the string starts with `prefix`.
688716

689717
Example:
690718

691719
```javascript
692-
S("JP is a software engineer").startsWith("JP"); //true
693-
S('wants to change the world').startsWith("politicians"); //false
720+
S('JP is a software engineer').startsWith('JP'); //true
721+
S('wants to change the world').startsWith('politicians'); //false
694722
```
695723

696724

@@ -997,7 +1025,7 @@ S('&lt;div&gt;hi&lt;/div&gt;').unescapeHTML().s; //<div>hi</div>
9971025

9981026
### - wrapHTML() ###
9991027

1000-
wrapHTML helps to avoid concatenation of element with string.
1028+
wrapHTML helps to avoid concatenation of element with string.
10011029
the string will be wrapped with HTML Element and their attributes.
10021030

10031031
Example:
@@ -1101,8 +1129,9 @@ If you contribute to this library, just modify `string.js`, `string.test.js`, an
11011129
- [*] [Nathan Friedly](https://github.com/nfriedly)
11021130
- [*] [Alison Rowland](https://github.com/arowla)
11031131
- [*] [Pascal Bihler](https://github.com/pbihler)
1132+
- [*] [Daniel Diekmeier](https://github.com/danieldiekmeier)
1133+
11041134

1105-
11061135

11071136
Roadmap to v2.0
11081137
---------------
@@ -1135,6 +1164,3 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
11351164
[aboutjp]: http://about.me/jprichardson
11361165
[twitter]: http://twitter.com/jprichardson
11371166
[procbits]: http://procbits.com
1138-
1139-
1140-

lib/_splitLeft.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function splitLeft(self, sep, maxSplit, limit) {
2+
3+
if (typeof maxSplit === 'undefined') {
4+
var maxSplit = -1;
5+
}
6+
7+
var splitResult = self.split(sep);
8+
var splitPart1 = splitResult.slice(0, maxSplit);
9+
var splitPart2 = splitResult.slice(maxSplit);
10+
11+
if (splitPart2.length === 0) {
12+
splitResult = splitPart1;
13+
} else {
14+
splitResult = splitPart1.concat(splitPart2.join(sep));
15+
}
16+
17+
if (typeof limit === 'undefined') {
18+
return splitResult;
19+
} else if (limit < 0) {
20+
return splitResult.slice(limit);
21+
} else {
22+
return splitResult.slice(0, limit);
23+
}
24+
25+
}
26+
27+
module.exports = splitLeft;

lib/_splitRight.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
function splitRight(self, sep, maxSplit, limit) {
2+
3+
if (typeof maxSplit === 'undefined') {
4+
var maxSplit = -1;
5+
}
6+
if (typeof limit === 'undefined') {
7+
var limit = 0;
8+
}
9+
10+
var splitResult = [self];
11+
12+
for (var i = self.length-1; i >= 0; i--) {
13+
14+
if (
15+
splitResult[0].slice(i).indexOf(sep) === 0 &&
16+
(splitResult.length <= maxSplit || maxSplit === -1)
17+
) {
18+
splitResult.splice(1, 0, splitResult[0].slice(i+sep.length)); // insert
19+
splitResult[0] = splitResult[0].slice(0, i)
20+
}
21+
}
22+
23+
if (limit >= 0) {
24+
return splitResult.slice(-limit);
25+
} else {
26+
return splitResult.slice(0, -limit);
27+
}
28+
29+
}
30+
31+
module.exports = splitRight;

lib/string.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,14 @@ string.js - Copyright (C) 2012-2014, JP Richardson <[email protected]>
347347
return new this.constructor(s);
348348
},
349349

350+
splitLeft: function(sep, maxSplit, limit) {
351+
return require('./_splitLeft')(this.s, sep, maxSplit, limit)
352+
},
353+
354+
splitRight: function(sep, maxSplit, limit) {
355+
return require('./_splitRight')(this.s, sep, maxSplit, limit)
356+
},
357+
350358
strip: function() {
351359
var ss = this.s;
352360
for(var i= 0, n=arguments.length; i<n; i++) {
@@ -451,11 +459,11 @@ string.js - Copyright (C) 2012-2014, JP Richardson <[email protected]>
451459
times: function(n) {
452460
return new this.constructor(new Array(n + 1).join(this.s));
453461
},
454-
462+
455463
titleCase: function() {
456464
var s = this.s;
457465
if (s) {
458-
s = s.replace(/(^[a-z]| [a-z]|-[a-z]|_[a-z])/g,
466+
s = s.replace(/(^[a-z]| [a-z]|-[a-z]|_[a-z])/g,
459467
function($1){
460468
return $1.toUpperCase();
461469
}

test/string.test.js

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,112 @@
420420
})
421421
})
422422

423+
describe('- splitLeft(sep, [maxSplit, [limit]])', function() {
424+
it('should return an array of strings, split from the left at sep, at most maxSplit splits, at most limit elements', function() {
425+
// by a char
426+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitLeft('|'))
427+
ARY_EQ (['a', 'b|c|d'], S('a|b|c|d').splitLeft('|', 1))
428+
ARY_EQ (['a', 'b', 'c|d'], S('a|b|c|d').splitLeft('|', 2))
429+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitLeft('|', 3))
430+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitLeft('|', 4))
431+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitLeft('|', 1000))
432+
ARY_EQ (['a|b|c|d'], S('a|b|c|d').splitLeft('|', 0))
433+
ARY_EQ (['a', '', 'b||c||d'], S('a||b||c||d').splitLeft('|', 2))
434+
ARY_EQ (['', ' begincase'], S('| begincase').splitLeft('|'))
435+
ARY_EQ (['endcase ', ''], S('endcase |').splitLeft('|'))
436+
ARY_EQ (['', 'bothcase', ''], S('|bothcase|').splitLeft('|'))
437+
438+
ARY_EQ (['a', 'b', 'c\x00\x00d'], S('a\x00b\x00c\x00\x00d').splitLeft('\x00', 2))
439+
440+
// by string
441+
ARY_EQ (['a', 'b', 'c', 'd'], S('a//b//c//d').splitLeft('//'))
442+
ARY_EQ (['a', 'b//c//d'], S('a//b//c//d').splitLeft('//', 1))
443+
ARY_EQ (['a', 'b', 'c//d'], S('a//b//c//d').splitLeft('//', 2))
444+
ARY_EQ (['a', 'b', 'c', 'd'], S('a//b//c//d').splitLeft('//', 3))
445+
ARY_EQ (['a', 'b', 'c', 'd'], S('a//b//c//d').splitLeft('//', 4))
446+
ARY_EQ (['a//b//c//d'], S('a//b//c//d').splitLeft('//', 0))
447+
ARY_EQ (['a', '', 'b////c////d'], S('a////b////c////d').splitLeft('//', 2)) // overlap
448+
ARY_EQ (['', ' begincase'], S('test begincase').splitLeft('test'))
449+
ARY_EQ (['endcase ', ''], S('endcase test').splitLeft('test'))
450+
ARY_EQ (['', ' bothcase ', ''], S('test bothcase test').splitLeft('test'))
451+
ARY_EQ (['a', 'bc'], S('abbbc').splitLeft('bb'))
452+
ARY_EQ (['', ''], S('aaa').splitLeft('aaa'))
453+
ARY_EQ (['aaa'], S('aaa').splitLeft('aaa', 0))
454+
ARY_EQ (['ab', 'ab'], S('abbaab').splitLeft('ba'))
455+
ARY_EQ (['aaaa'], S('aaaa').splitLeft('aab'))
456+
ARY_EQ ([''], S('').splitLeft('aaa'))
457+
ARY_EQ (['aa'], S('aa').splitLeft('aaa'))
458+
ARY_EQ (['A', 'bobb'], S('Abbobbbobb').splitLeft('bbobb'))
459+
ARY_EQ (['', 'B', 'A'], S('bbobbBbbobbA').splitLeft('bbobb'))
460+
461+
// with limit
462+
ARY_EQ (['a'], S('a|b|c|d').splitLeft('|', 3, 1))
463+
ARY_EQ (['a', 'b', 'c'], S('a|b|c|d').splitLeft('|', 3, 3))
464+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitLeft('|', 3, 4))
465+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitLeft('|', 3, 5))
466+
467+
ARY_EQ (['d'], S('a|b|c|d').splitLeft('|', 3, -1))
468+
ARY_EQ (['b', 'c|d'], S('a|b|c|d').splitLeft('|', 2, -2))
469+
ARY_EQ (['b', 'c', 'd'], S('a|b|c|d').splitLeft('|', 3, -3))
470+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitLeft('|', 3, -4))
471+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitLeft('|', 3, -5))
472+
473+
})
474+
})
475+
476+
describe('- splitRight(sep, [maxSplit, [limit]])', function() {
477+
it('should return an array of strings, split from the right at sep, at most maxSplit splits, at most limit elements', function() {
478+
// by a char
479+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitRight('|'))
480+
ARY_EQ (['a|b|c', 'd'], S('a|b|c|d').splitRight('|', 1))
481+
ARY_EQ (['a|b', 'c', 'd'], S('a|b|c|d').splitRight('|', 2))
482+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitRight('|', 3))
483+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitRight('|', 4))
484+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitRight('|', 1000))
485+
ARY_EQ (['a|b|c|d'], S('a|b|c|d').splitRight('|', 0))
486+
ARY_EQ (['a||b||c', '', 'd'], S('a||b||c||d').splitRight('|', 2))
487+
ARY_EQ (['', ' begincase'], S('| begincase').splitRight('|'))
488+
ARY_EQ (['endcase ', ''], S('endcase |').splitRight('|'))
489+
ARY_EQ (['', 'bothcase', ''], S('|bothcase|').splitRight('|'))
490+
491+
ARY_EQ (['a\x00\x00b', 'c', 'd'], S('a\x00\x00b\x00c\x00d').splitRight('\x00', 2))
492+
493+
// by string
494+
ARY_EQ (['a', 'b', 'c', 'd'], S('a//b//c//d').splitRight('//'))
495+
ARY_EQ (['a//b//c', 'd'], S('a//b//c//d').splitRight('//', 1))
496+
ARY_EQ (['a//b', 'c', 'd'], S('a//b//c//d').splitRight('//', 2))
497+
ARY_EQ (['a', 'b', 'c', 'd'], S('a//b//c//d').splitRight('//', 3))
498+
ARY_EQ (['a', 'b', 'c', 'd'], S('a//b//c//d').splitRight('//', 4))
499+
ARY_EQ (['a//b//c//d'], S('a//b//c//d').splitRight('//', 0))
500+
ARY_EQ (['a////b////c', '', 'd'], S('a////b////c////d').splitRight('//', 2)) // overlap
501+
ARY_EQ (['', ' begincase'], S('test begincase').splitRight('test'))
502+
ARY_EQ (['endcase ', ''], S('endcase test').splitRight('test'))
503+
ARY_EQ (['', ' bothcase ', ''], S('test bothcase test').splitRight('test'))
504+
ARY_EQ (['ab', 'c'], S('abbbc').splitRight('bb'))
505+
ARY_EQ (['', ''], S('aaa').splitRight('aaa'))
506+
ARY_EQ (['aaa'], S('aaa').splitRight('aaa', 0))
507+
ARY_EQ (['ab', 'ab'], S('abbaab').splitRight('ba'))
508+
ARY_EQ (['aaaa'], S('aaaa').splitRight('aab'))
509+
ARY_EQ ([''], S('').splitRight('aaa'))
510+
ARY_EQ (['aa'], S('aa').splitRight('aaa'))
511+
ARY_EQ (['bbob', 'A'], S('bbobbbobbA').splitRight('bbobb'))
512+
ARY_EQ (['', 'B', 'A'], S('bbobbBbbobbA').splitRight('bbobb'))
513+
514+
// with limit
515+
ARY_EQ (['d'], S('a|b|c|d').splitRight('|', 3, 1))
516+
ARY_EQ (['b', 'c', 'd'], S('a|b|c|d').splitRight('|', 3, 3))
517+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitRight('|', 3, 4))
518+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitRight('|', 3, 5))
519+
520+
ARY_EQ (['a'], S('a|b|c|d').splitRight('|', 3, -1))
521+
ARY_EQ (['a|b', 'c'], S('a|b|c|d').splitRight('|', 2, -2))
522+
ARY_EQ (['a', 'b', 'c'], S('a|b|c|d').splitRight('|', 3, -3))
523+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitRight('|', 3, -4))
524+
ARY_EQ (['a', 'b', 'c', 'd'], S('a|b|c|d').splitRight('|', 3, -5))
525+
526+
})
527+
})
528+
423529
describe('- strip([string1],[string2],...)', function() {
424530
it('should return the new string with all occurrences of [string1],[string2],... removed', function() {
425531
T (S('which ones will it take out one wonders').strip('on', 'er').s === 'which es will it take out e wds');
@@ -545,7 +651,7 @@
545651

546652
var str = "{{greet }} {{ name}}! How are you doing during the year of {{ date-year }}?";
547653
EQ (S(str).template(values).s, 'Hello JP! How are you doing during the year of 2013?')
548-
654+
549655
str = "Hello #{name}! How are you doing during the year of #{date-year}?"
550656
EQ (S(str).template(values, '#{', '}').s, 'Hello JP! How are you doing during the year of 2013?')
551657

@@ -614,7 +720,7 @@
614720
T (S('*').times(3).s === '***');
615721
})
616722
})
617-
723+
618724
describe('- titleCase()', function() {
619725
it('should upperCase all words in a camel cased string', function() {
620726
EQ (S('dataRate').titleCase().s, 'DataRate')

0 commit comments

Comments
 (0)