Reputation: 315
So In my program I can receive strings of all kinds of lengths and send them on their way to get translated. If those strings are of a certain character length I receive an error, so I want to check & split those strings if necessary before that. BUT I can't just split the string in the middle of a word, the words themself also need to be intact & taken into account.
So for example:
let str = "this is an input example of one sentence that contains a bit of words and must be split"
let splitStringArr = [];
// If string is larger than X (for testing make it 20) characters
if(str.length > 20) {
// Split string sentence into smaller strings, keep words intact
//...
// example of result would be
// splitStringArr = ['this is an input', 'example of one sentence' 'that contains...', '...']
// instead of ['this is an input exa' 'mple of one senten' 'ce that contains...']
}
But I'm not sure how to split a sentence and still keep into account the sentence length.
Would a solution for this be to iterate over the string, add every word to it and check every time if it is over the maximum length, otherwise start a new array index, or are there better/existing methods for this?
Upvotes: 3
Views: 3713
Reputation: 3032
I would suggest:
1) split string by space symbol, so we get array of words
2) starting to create string again selecting words one by one...
3) if next word makes the string exceed the maximum length we start a new string with this word
Something like this:
const splitString = (str, lineLength) => {
const arr = ['']
str.split(' ').forEach(word => {
if (arr[arr.length - 1].length + word.length > lineLength) arr.push('')
arr[arr.length - 1] += (word + ' ')
})
return arr.map(v => v.trim())
}
const str = "this is an input example of one sentence that contains a bit of words and must be split"
console.log(splitString(str, 20))
Upvotes: 2
Reputation: 63524
Here's an example using reduce
.
const str = "this is an input example of one sentence that contains a bit of words and must be split";
// Split up the string and use `reduce`
// to iterate over it
const temp = str.split(' ').reduce((acc, c) => {
// Get the number of nested arrays
const currIndex = acc.length - 1;
// Join up the last array and get its length
const currLen = acc[currIndex].join(' ').length;
// If the length of that content and the new word
// in the iteration exceeds 20 chars push the new
// word to a new array
if (currLen + c.length > 20) {
acc.push([c]);
// otherwise add it to the existing array
} else {
acc[currIndex].push(c);
}
return acc;
}, [[]]);
// Join up all the nested arrays
const out = temp.map(arr => arr.join(' '));
console.log(out);
Upvotes: 5
Reputation: 35011
What you are looking for is lastIndexOf
In this example, maxOkayStringLength is the max length the string can be before causing an error.
myString.lastIndexOf(/\s/,maxOkayStringLength);
-- edit --
lastIndexOf doesn't take a regex argument, but there's another post on SO that has code to do this:
Is there a version of JavaScript's String.indexOf() that allows for regular expressions?
Upvotes: 2
Reputation: 37755
You can use match and lookahead and word boundaries, |.+
to take care string at the end which are less then max length at the end
let str = "this is an input example of one sentence that contains a bit of words and must be split"
console.log(str.match(/\b[\w\s]{20,}?(?=\s)|.+$/g))
Upvotes: 5