patternjavascriptMinor
Trim to the nearest word under limit
Viewed 0 times
trimthenearestlimitunderword
Problem
Given a text and the length limit I need to trim the text to the word which is nearest to the limit.
O/P:
function trim(text, limit) {
if (text.length {
console.log(trim('Hello World', limit));
});O/P:
//
Hello
Hello
Hello
Hello World
Hello WorldSolution
The current code has a bug when the limit is exactly is exactly the length of a word. For example,
will return an empty string, when it should return
The issue stems from the loop over
Then, there are slight adjustements to make:
There is a simpler and efficient way to tackle this problem, using the built-in lastIndexOf(searchValue, fromIndex)
if (limit >= text.length) {
return text;
}
return text.substring(0, text.lastIndexOf(' ', limit));
}
[0, 2, 4, 5, 6, 8, 10, 11, 12, 50].forEach((limit) => {
console.log(limit + ' -> ' + trim('Hello World', limit));
});
If either argument is less than 0 [...], it is treated as if it were 0.
trim('Hello World', 5)will return an empty string, when it should return
"Hello", since it is of length 5, therefore it fits in the length limit.The issue stems from the loop over
i going from 0 to limit - 1 (excluded). The variable end represents the index of the last character to keep in the string, (because the method is returning text.substring(0, end + 1)). Therefore, it could be the case that end is equal to limit - 1, this happens when the limit falls right before a space. For example, when the limit is 5, and the string is 'Hello World', the last character to keep is 'o' at index 4. So the loop should go up to limit (excluded).Then, there are slight adjustements to make:
- The early-return testing
text.length
- The added check if (i === text.length - 1)
can safely be removed as a consequence: the only case whereiwould be equal totext.length - 1is iflimit == text.length(sinceigoes up tolimit - 1included). But that was already handled with the modified early-return.
There is a simpler and efficient way to tackle this problem, using the built-in lastIndexOf(searchValue, fromIndex)
. This method starts at the specified fromIndex, and searches backwards the first occurence of the given value. If we tell it to search the first occurence of ' ' searching backwards from limit, we'll exactly have the length of the substring to return.
The only corner case is if limit is greater than the length of the string, in which case the method should simply return the text unchanged (like the current code is doing). It needs to be tested separately; otherwise lastIndexOf would start searching from the end of the string, and the last word would always be cut. This is what it could look like:
function trim(text, limit) {if (limit >= text.length) {
return text;
}
return text.substring(0, text.lastIndexOf(' ', limit));
}
[0, 2, 4, 5, 6, 8, 10, 11, 12, 50].forEach((limit) => {
console.log(limit + ' -> ' + trim('Hello World', limit));
});
Note that, even if the lastIndexOf call returns -1, because there was no space character found before the limit length, it is still safe to call substring` since:If either argument is less than 0 [...], it is treated as if it were 0.
Code Snippets
trim('Hello World', 5)Context
StackExchange Code Review Q#151956, answer score: 4
Revisions (0)
No revisions yet.