`String.prototype.trimStart`/`String.prototype.trimEnd` with a given string

# Jacob Pratt (5 years ago)

String.prototype.padStart and String.prototype.padEnd accept the string to pad with as their final parameter. Is there any particular reason String.prototype.trimStart and String.prototype.trimEnd don't do the same? It would be nice to have a parallel, such that 'foo'.padEnd(10, 'bar').trimEnd('bar') === 'foo'.

References:

Jacob Pratt

# Jordan Harband (5 years ago)

trimStart and trimEnd are better-named versions of the very very long-existing trimLeft and trimRight, which lack this ability, along with ES5's trim.

It wouldn't make sense for these three to differ.

It certainly seems like a potential language proposal to add a string argument to all three; however, at what point is that reimplementing string.replace(/^(foo)+/, ''), string.replace(/(foo)+$/, ''), and string.replace(/^(foo)+|$(foo)+$/, '')? How common is the use case to trim matching substrings off of the ends of a string? (the use cases for padding were quite common)

# Jacob Pratt (5 years ago)

No idea how common of a use case this is; I personally ran across it when reviewing the source code for marked (specifically the rtrim method). That example only does characters, not strings, but it's used in the wild by a package with ~2m weekly downloads on npm.

Of course we wouldn't want trimStart to differ from trimLeft, they'd all be modified in unison. I just think that symmetry between similar methods is important, and (apparently) has use cases.

# kai zhu (5 years ago)

fyi, a search of the entire markedjs/marked repo shows 2 places where rtrim is used:

// https://github.com/markedjs/marked/blob/master/lib/marked.js
227
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L227>

codeBlockStyle: 'indented',
228
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L228>

text: !this.options.pedantic
229
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L229>
? rtrim(cap, '\n')
230
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L230>
: cap
…
1425
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1425>

baseUrls[' ' + base] = rtrim(base, '/', true);
1426
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1426>
}

1427
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1427>
}

1428
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1428>

base
= baseUrls[' ' + base];
1429
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1429>

1430
<https://github.com/markedjs/marked/blob/5ba9ba5b93b95096445249c11b31c13f7514137a/lib/marked.js#L1430>

if (href.slice(0, 2) === '//') {

only the 1st use-case does what this thread proposes (the 1st trimRight's "\n", while the 2nd behaves differently and is more like nodejs' require("path").dirname()

if i were writing the library, i wouldn't have bothered with a helper-function if its only going to show up in 2 [trivial] places. would've instead inlined two throwaway regexp-expressions, to keep code more-self-contained / less-fragmented:

228          text: !this.options.pedantic
229            ? cap.replace((/\n+$/), "") // remove trailing "\n" or
perhaps just use .trimRight()
230            : cap
…
1425      baseUrls[' ' + base] = base.replace((/\/[^\/]*$/), "/"); // get
"dirname" of base-url
1426    }
# Jacob Pratt (5 years ago)

Just thinking about this, the argument that it could be done with regex would also apply to spaces. It's by no means an argument in favor, but it clearly wasn't a blocker.

# Jordan Harband (5 years ago)

That's also true, although I believe \s in a regex includes line terminators that trim's concept of whitespace does not.