Why is my Palindrome code running true for every scenario? - javascript

This code returns true for every scenario; it returns true if it's a palindrome and it returns true if it's not a palindrome.
function isPalindrome(string){
string = string.toLowerCase();
var charactersArr = string.split(' ');
var validCharacters = 'abcdefghijklmnopqrstuvwxyz'.split(' ');
var lettersArr = [];
charactersArr.forEach(char => {
if (validCharacters.indexOf(char)> - 1) lettersArr.push(char);
});
return lettersArr.join(' ') === lettersArr.reverse().join(' ');
}
isPalindrome("Taco Cat");

function palindrome(str) {
var re = /[^A-Za-z0-9]/g;
str = str.toLowerCase().replace(re, '');
var len = str.length;
for (var i = 0; i < len/2; i++) {
if (str[i] !== str[len - 1 - i]) {
return false;
}
}
return true;
}
Use this code for checking palindromes . You are complicating your code by passing in var validCharacters = 'abcdefghijklmnopqrstuvwxyz'.split(' ');
You could use re like I have to include all possible combinations including numbers !

It always returns true because lettersArr is always empty. Try to debug your code using debugger or just use console.log for this purpose.
I believe at least this line var charactersArr = string.split(' '); is not doing what is expected: it splits a sentence by space characters into words instead of splitting into separate letters.

It's because lettersArris always empty .... Try this code:
function isPalindrome(string) {
let reversed = string.toLowerCase().split('').reverse().join('');
return reversed === string.toLowerCase()
}
let result1 = isPalindrome("Foo bar")
let result2 = isPalindrome("mom")
console.log(result1, result2)

lettersArr is not what you expect.
You are splitting the input string by spaces, which means you get ['taco', 'cat'] and not ['t', 'a', 'c', 'o', 'c', 'a', 't'].
Then when this line runs:
if (validCharacters.indexOf(char)> - 1) lettersArr.push(char);
char is 'taco' which isn't found in validCharacters, so nothing gets pushed into lettersArr.
And since lettersArr is empty:
lettersArr.join(' ') === lettersArr.reverse().join(' ');
Becomes:
[].join(' ') === [].reverse().join(' ')
Which, of course, it always true.
To fix it you simply want to split the string by an empty string, which gives you array of single character strings.
function isPalindrome(string){
string = string.toLowerCase();
var charactersArr = string.split('');
var validCharacters = 'abcdefghijklmnopqrstuvwxyz'.split('');
var lettersArr = [];
charactersArr.forEach(char => {
if (validCharacters.indexOf(char)> - 1) lettersArr.push(char);
});
return lettersArr.join(' ') === lettersArr.reverse().join(' ');
}
console.log("Taco Cat", isPalindrome("Taco Cat"));
console.log("abc", isPalindrome("abc"));

Related

homework assignment function given a string, loop through and console.log() only the vowels. I'm stuck on one thing

I have a function takes a string and logs only the vowels of this string. Currently each vowel is logged on a new line and that is no good.
function vowelsOnly(str) {
let vowels = ['a','e','i','o','u'];
for (let i = 0; i < str.length; i++) {
if (vowels.indexOf(str[i]) > -1 ) {
// newstr convert to string
let newstr = str[i].toString();
console.log(newstr);
}
// if no vowels in str log empty string
else {
console.log("");
}
}
}
I need assistance making my code replicate this example: Input is "welcome to my world" expected output is "eoeoo" no commas.
Thank you for your time.
EDIT this code is working for me.
const str = "qqwwrrttppssddaeu"
const vowels = str => str.split('').filter(i=>"aeiou".includes(i)).join('');
let newstr = vowels(str).length;
if (newstr > 1){
console.log(vowels(str));
}
else {
console.log("");
}
Have a look at string iterators to iterate over string.
Obviously the input needs to be processed to generate the result which goes to console.log. The effective tool to do it would be Array.prototype.filter which iterates the array implicitly. The array could be obtained by String.prototype.split. To put it together, the algorithm can be expressed as
const vowels = str => str.split('').filter(i=>"aeiou".includes(i)).join('');
So you can get the result by calling
console.log(vowels("welcome to my world"))
Enjoy functional javascript.
Store all vowels in an array. Then join the array and return it
const str = 'asdrqwfsdgobopwkodvcxvuqbe'
console.log(vowelsOnly(str))
function vowelsOnly(str) {
const result = []
let vowels = ['a', 'e', 'i', 'o', 'u'];
for (let i = 0; i < str.length; i++) {
if (vowels.indexOf(str[i]) > -1) {
result.push(str[i])
}
}
return result.join('')
}
one-liner
const str = 'asdrqwfsdgobopwkodvcxvuqbe'
console.log(str.match(/[aeiou]/g).join(''))

How to join strings in a for loop in Javascript?

I am trying to capitalise the first character of each word and join all words into one string. I have managed to capitalise the first character of each word but cant seem to get .join() to work on the final result
function generateHashtag (str) {
let split = str.split(' ')
for(let i = 0; i < split.length; i++){
let finalResult = split[i].charAt(0).toUpperCase() + split[i].substring(1)
console.log(finalResult.join(''))
}
}
console.log(generateHashtag('Hello my name is')) should return ('HelloMyNameIs')
Achieving this by split is possible. first create an array of divided strings (by the delimiter ' ') and then loop around the array and capitalize the first char using the method toUpperCase and concat the rest of the string without the first letter using slice
function generateHashtag(str) {
let split = str.split(' ');
for (let i = 0; i < split.length; i++) {
split[i] = split[i].charAt(0).toUpperCase() + split[i].slice(1);
}
return split.join('');
}
console.log(generateHashtag('Hello my name is'));
More about split - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
you can do split[i] = split[i].charAt(0).toUpperCase() + split[i].substring(1) in the loop then outside loop do split.join('')
Basically you are replacing each word (split[i]) with capitalised word. Then in the end join the words.
finalResult is a String, not an Array so there is no join function.
Use this instead :
function generateHashtag (str) {
let arrayWords = str.split(' ')
const titleCasedArray = arrayWords.map(word => titleCaseWord(word))
return titleCasedArray.join('');
}
function titleCaseWord (word){
return word.slice(0,1).toUpperCase() + word.slice(1,-1).toLowerCase()
}
You can do something like this:
function generateHashtag (str) {
//returns array of strings
let split = str.split(' ')
//returns array of strings with each word capitalized
const capitalizedWordsArr = split.map( word => word.charAt(0).toUpperCase() + word.substring(1))
//returns a string by joining above array with no spaces
return capitalizedWordsArr.join('')
}
This is a perfect use-case for Array.prototype.reduce:
function generateHashtag(str) {
return str
.split(' ')
.reduce((acc, [firstLetter, ...rest]) => acc += `${firstLetter.toUpperCase()}${rest.join('')}`,
''
);
}
console.log(generateHashtag('Hello my name is')); // should return ('HelloMyNameIs')
Javascript strings are immutable so you cannot overwrite them on the go, but you can overwrite array elements.
By using String.prototype.substr() you can extract a part of the string, you can use these parts, modify it and create a new string then replace the old array element. finally returning the joined string like you wanted to
function generateHashtag(str) {
const split = str.split(' ') // array of words
for (let i = 0; i < split.length; i++)
split[i] = split[i].substr(0, 1).toUpperCase() + split[i].substr(1); // overwriting existing elements with Titlecased words
return split.join(''); // returning final string
}
console.log(generateHashtag('Hello my name is'))
You don't need to use join at all, just declare and initialize finalResult outside the loop and concatenate each word inside the loop:
function generateHashtag(str) {
const split = str.split(' '); // Array<String>
let finalResult = ''; // String
for(let i = 0; i < split.length; i++) {
const titleCased = split[i].charAt(0).toUpperCase() + split[i].substring(1);
finalResult += titleCased;
}
return finalResult;
}
console.log(generateHashtag('Hello my name is'));
However, you can simplify this code considerably by using a functional-programming (FP) style with map and reduce. See below.
I've also changed your code to use toLocaleUpperCase instead of toUpperCase and uses [0] for brevity.
It's still safe to use substring(1) for single-character strings, it just returns ''.
function generateHashtag(str) {
return ( str
.split(' ')
.map( word => word[0].toLocaleUpperCase() + word.substring(1).toLocaleLowerCase() )
.reduce( ( word, concat ) => concat + word, "" )
);
}
I forgot that join() can still be used instead of reduce (and will have an optimized implementation inside the JS engine anyway):
I've also moved the map function's logic to a named function toTitleCase.
function generateHashtag(str) {
const toTitleCase( word ) => word[0].toLocaleUpperCase() + word.substring(1).toLocaleLowerCase();
return ( str
.split(' ')
.map( word => toTitleCase( word ) ) // or just `.map( toTitleCase )`
.join()
);
}
The return statement has parens to prevent unwanted automatic-semicolon-insertion which would otherwise break the function.
If you want something similar to your code, but working, i would do this:
function generateHashtag (str) {
let split = str.split(' ')
let newStr = []
for (let i = 0; i < split.length; i++){
newStr.push(split[i].charAt(0).toUpperCase() + split[i].substring(1))
}
return newStr.join('')
}
You could also choose to do this task using a 'regular expression'.
https://cheatography.com/davechild/cheat-sheets/regular-expressions/
Here is a quick implementation:
const generateHashtag = str => {
// regular expression to capitalize the words
const regEx = /(\b[a-z](?!\s))/g
str = str.replace(regEx, (char) => {
return char.toUpperCase()
});
// remove spaces, return
return str.split(' ').join('')
}
Same code, but with less readability:
const generateHashtag = str => {
return str.replace(/(\b[a-z](?!\s))/g, (char) => {
return char.toUpperCase()
}).split(' ').join('');
}
function generateHashtag (str) {
return str.replace(/\b\S/g, e => e.toUpperCase()).replace(/\s/g,'');
}
console.log(generateHashtag('Hello my name is'))
\b: bondary \S: non space \s: space.
https://regex101.com/
//try this code solve your problem
const generateHashtag = str => {
let split = str.split(' ')
let finalResult = []
for (word of split) {
finalResult.push(word[0].toUpperCase() + word.substring(1))
}
return finalResult.join('')
}
console.log(generateHashtag('Hello my name is'))

Determine if string has at least 2 same elements from an array

I want to determine if string has at least 2 same elements from the array
const array = ["!", "?"];
const string1 = "!hello"; // should return false
const string2 = "!hello?"; // should return false
const string3 = "!hello!"; // should return true
const string4 = "hello ??"; // should return true
const string5 = "hello ?test? foo"; // should return true
const string6 = "hello ?test ?? foo"; // should return true
I'm not sure what is gonna be better: a regex or a function? Any would be fine.
I tried this:
const array = ["!", "?"];
const string = "test!";
array.every(ar => !string.includes(ar));
But it only detects if there at least 1 elements from array, not 2.
You can use Array#some and String#split to do it:
const check=(array,string)=>array.some(char=>(string.split(char).length-1)>=2)
const array = ["!", "?"];
console.log(check(array,"!hello"))
console.log(check(array,"!hello?"))
console.log(check(array,"!hello!"))
console.log(check(array,"hello ??"))
console.log(check(array,"hello ?test? foo"))
console.log(check(array, "hello ?test ?? foo"))
How does it work?
Let's split up (I mean to split() up)!
const check=(array,string)=>
array.some(char=>
(
string.split(char)
.length-1
)>=2
)
First, use Array#some, which tests that at least one element of the array should pass (i.e. either ? or !)
Split up the string by char, and count how many parts do we have
If we have n parts, it means that we have n-1 places where the char matches. (e.g. 2 | splits a string into 3 parts: a|b|c)
Finally, test whether we have 2 or more delimiters
Another way is to use a pattern with a capturing group and a dynamically created character class for [!?] and a backreference \1 to what is captured in group 1 to make sure there are 2 of the same characters present.
([!?]).*\1
Regex demo
For example
const array = ["!", "?"];
const regex = new RegExp("([" + array.join(("")) + "]).*\\1");
[
"!hello",
"!hello?",
"!hello!",
"hello ??",
"hello ?test? foo",
"hello ?test ?? foo"
].forEach(str => console.log(str + ": " + regex.test(str)));
You can use string split and array length like:
const array = ["!", "?"];
const string6 = "hello ?test ?? foo";
var len1 = string6.split(array[0]).length;
var len2 = string6.split(array[1]).length;
if (len>2)||(len2>2)
return true;
EDIT: Using for loop
for (let i=0;i<array.length;i++){
var len = string6.split(array[i]).length;
if (len>2)
return true;
}
return false;
You can follow a very simple solution like below. Split the string using the character in array. check the left of the split operation. If the length is minimum 2, then return true, else false.
Here is a sample jsFiddle: https://jsfiddle.net/sagarag05/qk8f2Lz7/
const array = ["!", "?"];
var str = "How are you!! doing !today?";
function isFound(arr, str){
var isPresent = false;
for(var i=0; i < arr.length; i++){
var res = str.split(arr[i]);
if(res.length-1 >= 2){
isPresent = true;
break;
}
}
return isPresent;
}
isFound(array, str);
Create a function which can be handy for n number of occurrences to find
const arrayData = ["!", "?"];
const strData = "test!";
function checkElements(arr, str, occNum) {
var ctr = 0;
arr.forEach(function (elem) { if(str.includes(elem)) ctr++});
return ctr >= occNum
}
checkElements(arrayData, strData, 2)
Use loop over array and count occurrence then check if occurrence is greater than 1.
function has2(string1, array)
{
for(let i=0;i<array.length;i++)
{
if (string1.split('').reduce(function(n, val) {
return n + (val === array[i]);
}, 0) > 1)
{
return true;
}
}
return false;
}
console.log(has2("!hello!", ["!", "?"])); // true
console.log(has2("!hello?", ["!", "?"])); // false
Here is a regex trick approach. We can try removing all characters from the input which are not part of the character class of characters to find. Then, assert that there are at least two distinct characters remaining in the input.
var input = "!hello?";
input = input.replace(/[^!?]+/g, "");
if (/(.).*(?!\1)./.test(input)) {
console.log("MATCH");
}
else {
console.log("NO MATCH");
}
The logic here is fairly straightforward. Using the input !hello? as an example, we first remove all non marker characters, leaving us with !?. Then, we use a regex to assert that there are at least two distinct characters remaining. This is true for this input, so we print MATCH.
Edit:
To build the regex alternation from your input array use join:
const array = ["!", "?"];
var regex = "[^" + array.join("") + "]+";
There is a much simpler solution for this:
var a = ["!", "?"], s = "!hello!";
a.some(v=>s.split(v).length>2) // (returns true if multiples are found)
We can turn it into a function to test:
const a = ["!", "?"];
function Test(s) { return a.some(v => s.split(v).length > 2) }
const string1 = "!hello"; // should return false
const string2 = "!hello?"; // should return false
const string3 = "!hello!"; // should return true
const string4 = "hello ??"; // should return true
const string5 = "hello ?test? foo"; // should return true
const string6 = "hello ?test ?? foo"; // should return true
console.log(Test(string1), Test(string2), Test(string3), Test(string4),
Test(string5), Test(string6));
> false false true true true true
Note: My code changed a few times and in the end was close to the accepted answer and I didn't realize. That said, you don't need to subtract anything, so that part is unnecessary.
function checkDups(arr, str) {
var ctr = [];
for (var i = 0; i < arr.length; i++) {
var pos = str.indexOf(arr[i]);
var count = 0;
ctr[i] = 0;
while (pos > -1) {
++count;
pos = str.indexOf(arr[i], ++pos);
}
if (count >= 2) {
return true
}
}
return false
}
console.log(checkDups(["!", "?"], "!hello"))
console.log(checkDups(["!", "?"], "!hello?"))
console.log(checkDups(["!", "?"], "!hello!"))
console.log(checkDups(["!", "?"], "hello ??"))
console.log(checkDups(["!", "?"], "hello ?test? foo"))
console.log(checkDups(["!", "?"], "hello ?test ?? foo"))

Replace multiple parts of string simultaneously

Say I had the following code:
var str = "abcde";
str.replace("a", "ab")
str.replace("b", "c")
The value of str go from abcde to abbcde to acccde. How would I go about making it so that the two operations happen simultaneously, so that the value of str instead goes from abcde to abccde?
EDIT: I'm talking about any situation similar to this, not just this specific one.
When replace contains these kind of patterns, first do which is indepndent and then other like below.
var str = "abcde";
str.replace("b", "c");
str.replace("a", "ab");
Or else replace both of them using some map:
var str = "abcde";
var mapObj = {
a:"ab",
b:"c"
};
str = str.replace(/a|b/gi, function(matched){
return mapObj[matched];
});
console.log(str);
Output:
abccde
You need to match both a and b with a regular expression, then use a function to distinguish whether it was an a or an b. See documentation for the replace function.
var str = 'abcde'
var newStr = str.replace(/[ab]/g, function (match) {
switch (match) {
case 'a':
return 'ab'
case 'b':
return 'c'
default:
return '???' // or throw error
}
})
console.log(newStr) // -> abccde
If you have a list of strings that you want to replace, you might want to look at how to escape strings to be used in regular expressions, then use the constructor for RegExp to construct the regular expression to be used for the replace function.
var replacements = {'a': 'ab', 'b': 'c'}
var keys = Object.keys(replacements)
// escapeRegExp function from https://stackoverflow.com/a/6969486/8557739
var escapedKeys = keys.map(escapeRegExp)
var re = RegExp(escapedKeys.join('|'), 'g') // re = /a|b/g
// then continue on like before
var str = 'abcde'
var newStr = str.replace(re, function (match) {
for (var key in replacements) {
if (match === key) {
return replacements[key]
}
}
return '???' // or throw error
})
console.log(newStr) // -> abccde
var str = "abcde";
str.replace(/a|b/gbbc);
You can use this regex as well, as it will replace 'a' with 'b' and 'b' with 'bc'.
If you want to apply this regex globally for your String then you can use '/g' as mentioned above else just a / after b.
To chain replacement, use '|' operator as I did between a|b.
I have found a way to do it using arrays.
var str = "abcde";
var str2 = str.split("");
for(var i = 0; i < str2.length; i++){
if(str2[i] === "a"){
str2[i] = "ab"
} else if(str2[i] === "b"){
str2[i] = "c";
}
}

Javascript How to split string by symbols count [duplicate]

As the title says, I've got a string and I want to split into segments of n characters.
For example:
var str = 'abcdefghijkl';
after some magic with n=3, it will become
var arr = ['abc','def','ghi','jkl'];
Is there a way to do this?
var str = 'abcdefghijkl';
console.log(str.match(/.{1,3}/g));
Note: Use {1,3} instead of just {3} to include the remainder for string lengths that aren't a multiple of 3, e.g:
console.log("abcd".match(/.{1,3}/g)); // ["abc", "d"]
A couple more subtleties:
If your string may contain newlines (which you want to count as a character rather than splitting the string), then the . won't capture those. Use /[\s\S]{1,3}/ instead. (Thanks #Mike).
If your string is empty, then match() will return null when you may be expecting an empty array. Protect against this by appending || [].
So you may end up with:
var str = 'abcdef \t\r\nghijkl';
var parts = str.match(/[\s\S]{1,3}/g) || [];
console.log(parts);
console.log(''.match(/[\s\S]{1,3}/g) || []);
If you didn't want to use a regular expression...
var chunks = [];
for (var i = 0, charsLength = str.length; i < charsLength; i += 3) {
chunks.push(str.substring(i, i + 3));
}
jsFiddle.
...otherwise the regex solution is pretty good :)
str.match(/.{3}/g); // => ['abc', 'def', 'ghi', 'jkl']
Building on the previous answers to this question; the following function will split a string (str) n-number (size) of characters.
function chunk(str, size) {
return str.match(new RegExp('.{1,' + size + '}', 'g'));
}
Demo
(function() {
function chunk(str, size) {
return str.match(new RegExp('.{1,' + size + '}', 'g'));
}
var str = 'HELLO WORLD';
println('Simple binary representation:');
println(chunk(textToBin(str), 8).join('\n'));
println('\nNow for something crazy:');
println(chunk(textToHex(str, 4), 8).map(function(h) { return '0x' + h }).join(' '));
// Utiliy functions, you can ignore these.
function textToBin(text) { return textToBase(text, 2, 8); }
function textToHex(t, w) { return pad(textToBase(t,16,2), roundUp(t.length, w)*2, '00'); }
function pad(val, len, chr) { return (repeat(chr, len) + val).slice(-len); }
function print(text) { document.getElementById('out').innerHTML += (text || ''); }
function println(text) { print((text || '') + '\n'); }
function repeat(chr, n) { return new Array(n + 1).join(chr); }
function textToBase(text, radix, n) {
return text.split('').reduce(function(result, chr) {
return result + pad(chr.charCodeAt(0).toString(radix), n, '0');
}, '');
}
function roundUp(numToRound, multiple) {
if (multiple === 0) return numToRound;
var remainder = numToRound % multiple;
return remainder === 0 ? numToRound : numToRound + multiple - remainder;
}
}());
#out {
white-space: pre;
font-size: 0.8em;
}
<div id="out"></div>
If you really need to stick to .split and/or .raplace, then use /(?<=^(?:.{3})+)(?!$)/g
For .split:
var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ )
// [ 'abc', 'def', 'ghi', 'jkl' ]
For .replace:
var replaced = str.replace( /(?<=^(?:.{3})+)(?!$)/g, ' || ' )
// 'abc || def || ghi || jkl'
/(?!$)/ is to not stop at end of the string. Without it's:
var arr = str.split( /(?<=^(?:.{3})+)/ )
// [ 'abc', 'def', 'ghi', 'jkl' ] // is fine
var replaced = str.replace( /(?<=^(.{3})+)/g, ' || ')
// 'abc || def || ghi || jkl || ' // not fine
Ignoring group /(?:...)/ is to prevent duplicating entries in the array. Without it's:
var arr = str.split( /(?<=^(.{3})+)(?!$)/ )
// [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ] // not fine
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' )
// 'abc || def || ghi || jkl' // is fine
My solution (ES6 syntax):
const source = "8d7f66a9273fc766cd66d1d";
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,2).join(''), 2));
We could even create a function with this:
function splitStringBySegmentLength(source, segmentLength) {
if (!segmentLength || segmentLength < 1) throw Error('Segment length must be defined and greater than/equal to 1');
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,segmentLength).join('')));
return target;
}
Then you can call the function easily in a reusable manner:
const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);
Cheers
const chunkStr = (str, n, acc) => {
if (str.length === 0) {
return acc
} else {
acc.push(str.substring(0, n));
return chunkStr(str.substring(n), n, acc);
}
}
const str = 'abcdefghijkl';
const splittedString = chunkStr(str, 3, []);
Clean solution without REGEX
My favorite answer is gouder hicham's. But I revised it a little so that it makes more sense to me.
let myString = "Able was I ere I saw elba";
let splitString = [];
for (let i = 0; i < myString.length; i = i + 3) {
splitString.push(myString.slice(i, i + 3));
}
console.log(splitString);
Here is a functionalized version of the code.
function stringSplitter(myString, chunkSize) {
let splitString = [];
for (let i = 0; i < myString.length; i = i + chunkSize) {
splitString.push(myString.slice(i, i + chunkSize));
}
return splitString;
}
And the function's use:
let myString = "Able was I ere I saw elba";
let mySplitString = stringSplitter(myString, 3);
console.log(mySplitString);
And it's result:
>(9) ['Abl', 'e w', 'as ', 'I e', 're ', 'I s', 'aw ', 'elb', 'a']
try this simple code and it will work like magic !
let letters = "abcabcabcabcabc";
// we defined our variable or the name whatever
let a = -3;
let finalArray = [];
for (let i = 0; i <= letters.length; i += 3) {
finalArray.push(letters.slice(a, i));
a += 3;
}
// we did the shift method cause the first element in the array will be just a string "" so we removed it
finalArray.shift();
// here the final result
console.log(finalArray);
var str = 'abcdefghijkl';
var res = str.match(/.../g)
console.log(res)
here number of dots determines how many text you want in each word.
function chunk(er){
return er.match(/.{1,75}/g).join('\n');
}
Above function is what I use for Base64 chunking. It will create a line break ever 75 characters.
Here we intersperse a string with another string every n characters:
export const intersperseString = (n: number, intersperseWith: string, str: string): string => {
let ret = str.slice(0,n), remaining = str;
while (remaining) {
let v = remaining.slice(0, n);
remaining = remaining.slice(v.length);
ret += intersperseWith + v;
}
return ret;
};
if we use the above like so:
console.log(splitString(3,'|', 'aagaegeage'));
we get:
aag|aag|aeg|eag|e
and here we do the same, but push to an array:
export const sperseString = (n: number, str: string): Array<string> => {
let ret = [], remaining = str;
while (remaining) {
let v = remaining.slice(0, n);
remaining = remaining.slice(v.length);
ret.push(v);
}
return ret;
};
and then run it:
console.log(sperseString(5, 'foobarbaztruck'));
we get:
[ 'fooba', 'rbazt', 'ruck' ]
if someone knows of a way to simplify the above code, lmk, but it should work fine for strings.
Coming a little later to the discussion but here a variation that's a little faster than the substring + array push one.
// substring + array push + end precalc
var chunks = [];
for (var i = 0, e = 3, charsLength = str.length; i < charsLength; i += 3, e += 3) {
chunks.push(str.substring(i, e));
}
Pre-calculating the end value as part of the for loop is faster than doing the inline math inside substring. I've tested it in both Firefox and Chrome and they both show speedup.
You can try it here
Here's a way to do it without regular expressions or explicit loops, although it's stretching the definition of a one liner a bit:
const input = 'abcdefghijlkm';
// Change `3` to the desired split length.
const output = input.split('').reduce((s, c) => {
let l = s.length-1;
(s[l] && s[l].length < 3) ? s[l] += c : s.push(c);
return s;
}, []);
console.log(output); // output: [ 'abc', 'def', 'ghi', 'jlk', 'm' ]
It works by splitting the string into an array of individual characters, then using Array.reduce to iterate over each character. Normally reduce would return a single value, but in this case the single value happens to be an array, and as we pass over each character we append it to the last item in that array. Once the last item in the array reaches the target length, we append a new array item.
Some clean solution without using regular expressions:
/**
* Create array with maximum chunk length = maxPartSize
* It work safe also for shorter strings than part size
**/
function convertStringToArray(str, maxPartSize){
const chunkArr = [];
let leftStr = str;
do {
chunkArr.push(leftStr.substring(0, maxPartSize));
leftStr = leftStr.substring(maxPartSize, leftStr.length);
} while (leftStr.length > 0);
return chunkArr;
};
Usage example - https://jsfiddle.net/maciejsikora/b6xppj4q/.
I also tried to compare my solution to regexp one which was chosen as right answer. Some test can be found on jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/. Tests are showing that both methods have similar performance, maybe on first look regexp solution is little bit faster, but judge it Yourself.
var b1 = "";
function myFunction(n) {
if(str.length>=3){
var a = str.substring(0,n);
b1 += a+ "\n"
str = str.substring(n,str.length)
myFunction(n)
}
else{
if(str.length>0){
b1 += str
}
console.log(b1)
}
}
myFunction(4)
function str_split(string, length = 1) {
if (0 >= length)
length = 1;
if (length == 1)
return string.split('');
var string_size = string.length;
var result = [];
for (let i = 0; i < string_size / length; i++)
result[i] = string.substr(i * length, length);
return result;
}
str_split(str, 3)
Benchmark: http://jsben.ch/HkjlU (results differ per browser)
Results (Chrome 104)

Categories