I'm trying to check whether some sentence is a palindrome. Word breaks and punctuation don't count.
This code using cStr.split(" ")
DOES NOT accomplish the task.
Splitting on whitespace (" "), it seems like reverse() does nothing.
const palindromes = (str) => {
const regex = /[!"#$%&'()* ,-./:;<=>?@[\]^_`{|}~]/g;
const cStr = str.toLowerCase().replace(regex, "").split(" ").join("");
const revStr = cStr.split(" ").slice().reverse().join("");
return cStr === revStr ? true : false;
};
UPDATED THOUGHTS: After I join the original string cStr
at the end, the characters are all collapsed. In the incorrect code I split on "whitespace" (split(" ")) which does not exist, so the code stops executing but doesn't throw an error?
The same code using [...cStr]
or cStr.split("")
DOES accomplish the task:
const revStr = cStr.split("").slice().reverse().join("");
// or
const revStr = [...cStr].slice().reverse().join("");
How is the "separator"; /""/ or /" "/ having this effect?
If separator is an empty string (""), str is converted to an array of each of its UTF-16 "characters", without empty strings on either ends of the resulting string.
Relevant question to array mutating: reverse-array-in-javascript-without-mutating-original-array
Relevant question to string manipulation: character-array-from-string
Split() doc: String.prototype.split()
CodePudding user response:
Seems you have read the docs of string.split
but not fully understood them. If you pass a separator, that doesn't exist in the string, it just returns an array with one element, this element being the whole string. Whereas if you split by an empty separator, it will split after every character.
let astring = "nowhitespacehere";
let splitstring1 = astring.split(" ");
console.log(splitstring1);
let splitstring2 = astring.split("");
console.log(splitstring2);
Well, in your first approach you remove all whitespaces from your string by
str.split(" ").join("");
Then later on you do
cStr.split(" ").slice().reverse().join("");
If you separate those steps do
.split(" ")
by whitespace. There is no whitespace anymore, thus, this returns an array with one element[cStr]
you
.slice()
from that array, which gives you another 1-element array[cStr]
you
.reverse()
that 1-element array, which gives you -- surprise surprise -- another 1-element arrray[cStr]
you
.join("")
the elements in this 1-element array with an empty separator, which gives youcStr
In your second approach you do
cStr.split("").slice().reverse().join("");
The crucial difference is the first split("")
by an empty separator, which splits the string after every character
No, your first approach doesn't "stop executing" it just does what you told it to do, split by a non-existant separator. And why would or should that throw an error? It just does, what the split is supposed to do. Add up all characters until you find a separator. If none is to be found, of course it will add up the whole string to the first token ...
CodePudding user response:
I optimized your original function a bit, while trying to understand your problem. Since @derpirscher already answered your question, I just want to add this as an inspiration (and not just throw it away :-)
With palindromes you compare letters, so there's no need to split the sentence into words.
const palindromes = (str) => {
const regex = /[^a-zA-Z]/g; // No need to specify all the characters, also removes whitespaces
const cStr = str.toLowerCase().replace(regex, ""); // No need to convert to array and back
const revStr = cStr.split("").reverse().join("");
return cStr === revStr; // This already returns true or false
};