I'm trying to make a function that will check if a word is a palindrome. If the word is a palindrome it will return true else it will return false. "You'll need to remove all non-alphanumeric characters (punctuation, spaces and symbols) and turn everything lower case in order to check for palindromes.
We'll pass strings with varying formats, such as "racecar", "RaceCar", and "race CAR" among others."
My code is:
function palindrome(str) {
str = str.toLowerCase().replace(/[^a-z]+/g,"");
if (str === str.split("").reverse().join("")){
return str;
} else {
return "This is not a palindrome";
}
}
Could somebody tell me what is wrong with this code please?
How about this solution.
function palindrome(str) {
str = str.toLowerCase().replace(/[^a-z0-9]+/g,"");
return str === str.split("").reverse().join("");
}
It strips non alpha-numeric characters, turns into lower case, and returns true | false
"alphanumeric" means both alphabetical and numerical characters. Try something like this:
function isPalindrome(str) {
str = str.toLowerCase().replace(/[^a-z0-9]+/g, '');
return str === str.split('').reverse().join('');
}
isPalindrome('racecar')
// => true
isPalindrome('race car')
// => true
isPalindrome('race caR')
// => true
It doesn't work because it always return a "true" because if not palindrome, then return a string, which evaluated as a boolean is true.
Related
JavaScript
This is the function which will give the output "true"if there is a repeated character in a string,,
otherwise it will give output "false"
function repeatChar(str) {
for (let char of str.toLowerCase()) {
if (str.indexOf(char) !== str.lastIndexOf(char)) {
return true;
}
}
return false;
}
console.log(repeatChar('aA')); //expected output "true" but here output is "false"... Why??
You're searching for the lowercased character in the original string, which hasn't been converted to all lowercase.
You should replace str with its lowercase version before the loop.
function repeatChar(str) {
str = str.toLowerCase();
for (let char of str) {
if (str.indexOf(char) !== str.lastIndexOf(char)) {
return true;
}
}
return false;
}
console.log(repeatChar('aA')); //expected output "true" but here output is "false"... Why??
Because str.toLowerCase() is ‘aa’ but you’re comparing occurrences in the original string ‘aA’:
// str is still ‘aA’
// str.toLowerCase() returns a *new string* and leaves str unchanged
str.indexOf(char) // “aA”.indexOf(‘a’) === 0
str.lastIndexOf(char) // “aA”.indexOf(‘a’) === 0
When you reference "str.indexOf(char)" in the "if" check you are not referencing the lower case version of str, but rather the original version with upper case.
If you want to reference the lower case version, you can do the following:
function repeatChar(str) {
for (let char of lower_str=str.toLowerCase()) {
if (lower_str.indexOf(char) !== lower_str.lastIndexOf(char)) {
return true;
}
}
return false;
}
console.log(repeatChar('aA'));
str='aA';
str.toLowerCase() is 'aa';
However, unless str is updated i.e. str=str.toLowerCase(), all references to str shall be to its original form i.e. 'aA'.
And, as you rightly know (given you are indeed attempting to use uniform case during comparison), the indexOf() and lastIndexOf() methods are case sensitive
A simpler way to do this would be to construct a Set from the string's characters and compare its size with the original string's length. If they are equal, then there were no repeated characters, as Sets contain only unique values.
function repeatChar(str) {
return new Set([...str.toLowerCase()]).size !== str.length;
}
In this example I split the string into an array then loop over each element of the array. I stored the previous character in the last variable.
function repeatChar(str) {
let last = '';
for (const char of str.toLowerCase().split('')) {
if (char === last) {
return true;
}
last = char;
}
return false;
}
console.log(repeatChar('aA'));
str.toLowerCase() will not change str
function palindrome(str) {
// Good luck!
var a = str.replace(/\s|[0-9_]|\W|[#$%^&*()]/g, "").toLowerCase();
if (a === a.split("").reverse().join("")) {
return true;
}
return false;
}
palindrome("eye");
palindrome("1 eye for of 1 eye.") //should return false.
I have done this task on freecodecampus.com. Can anyone tell me why it should give false? If we are removing dot and punctuations, then isn't it right that it should return true?
According to your comment "Note You'll need to remove all non-alphanumeric characters (punctuation, spaces and symbols)", you have to keep alphanumeric characters (ie. letters AND digits). So remove NON alphanum characters (ie. [\W_]). \W is the negation of \w: [^a-zA-Z0-9_]
This is done with:
var test = [
"racecar",
"RaceCar",
"race CAR",
"2A3*3a2",
"2A3 3a2",
"2_A3*3#A2",
"1 eye for of 1 eye."
];
function palindrome(str) {
var a = str.replace(/[\W_]+/g, "").toLowerCase();
if (a === a.split("").reverse().join("")) {
return true;
}
return false;
}
console.log(test.map(function (a) {
return a+' : '+palindrome(a);
}));
function palindrome(str) {
// Good luck!
var a = str.replace(/\s|[0-9_]|\W|[#$%^&*()]/g, "").toLowerCase();
// Here print a
// a = "eyeforofeye"; which is perfect palindrome
if (a === a.split("").reverse().join("")) {
// will pass this condition
return true;
}
return false;
}
palindrome("1 eye for of 1 eye.")
See my comments in the code. The replace method is using a regex to replace all numbers, special character and spaces with nothing. So all you get is a single word with no spaces, numbers and special characters.
In your case you will get eyeforofeye which is perfect palindrome.
You are doing a Rube Goldberg process by providing an overly complicated Regular Expression which could be shorten to /[^a-z]/ and it doesn't return false if you execute your code.
function palindrome(str) {
var a = str.replace(/[^a-z]/ig, '').toLowerCase();
return a === a.split('').reverse().join('');
}
console.log(palindrome('race CAR'));
console.log(palindrome('2A3 3a2'));
console.log(palindrome('eye'));
console.log(palindrome('1 eye for of 1 eye.'));
console.log(palindrome('stack'));
Thanks a lot folks, have done it; Also got some good information on RegeXes. Reading RegEx from Eloquent Javascript, can anyone suggest another better source? Thanx ahead
By the Way As an Answer it took this, ( for those who are interested in answer that passes all ticks in project) ,
function palindrome(str) {
// Good luck!
var a = str.replace(/[^a-z0-9]/ig, "").toLowerCase();
if (a === a.split("").reverse().join("")) {
return true;
}
return false;
}
palindrome("eye");
My Palindrome checker function works for single strings i.e. 'dog' it works, but when it is a phrase i.e. 'nurses run' it does not work! here is my code:
function palindromeCheck(string) {
return string === string.split('').reverse().join('');
}
function palindromeCheck(string) {
string = string.replace(/\s+/g,'');
return string === string.split('').reverse().join('');
}
The s+ character means to match any number of whitespace characters (including tabs). The g character means to repeat the search through the entire string. Read about this, and other RegEx modifiers available in JavaScript here.
Try this.
function palindromeCheck(string) {
string = string.replace(/\s/g, "");
return string === string.split('').reverse().join('');
}
console.log(palindromeCheck('nurses run'))
Trying to check for palindromes. I've checked other answers but none included punctuation & spaces.
"never odd or even" and "A man, a plan, a canal. Panama" Should return true but they don't.
function palindrome(str) {
if(str.replace(/[^\w\s]|_/g, "").toLowerCase() === str.replace(/[^\w\s]|_/g, "").toLowerCase().split("").reverse().join("")){
return true;
} else {
return false;
}
}
palindrome("eye");
I think you have an error in your RegEx. If you want to remove the spaces, you don't need that \s. Try changing:
str.replace(/[^\w\s]|_/g, "")
With
str.replace(/[^\w]|_/g, "")
Use instead:
str.replace(/\W/g, "")
Which will replace any non-word char by empty string.
You can try with a simpler regex which simply replaces any character that is not in the alphabet?
function palindrome(str) {
if(str.replace(/[^a-zA-Z]/g, "").toLowerCase() === str.replace(/[^a-zA-Z]/g, "").toLowerCase().split("").reverse().join("")){
return true;
} else {
return false;
}
}
This is similar to the above but reformatted:
function palindrome(str) {
let regex = /[^a-zA-Z]/g;
return str.replace(regex, '').toLowerCase() === str.replace(regex, '').toLowerCase().split('').reverse().join('');
}
How can I quickly validate if a string is alphabetic only, e.g
var str = "!";
alert(isLetter(str)); // false
var str = "a";
alert(isLetter(str)); // true
Edit : I would like to add parenthesis i.e () to an exception, so
var str = "(";
or
var str = ")";
should also return true.
Regular expression to require at least one letter, or paren, and only allow letters and paren:
function isAlphaOrParen(str) {
return /^[a-zA-Z()]+$/.test(str);
}
Modify the regexp as needed:
/^[a-zA-Z()]*$/ - also returns true for an empty string
/^[a-zA-Z()]$/ - only returns true for single characters.
/^[a-zA-Z() ]+$/ - also allows spaces
Here you go:
function isLetter(s)
{
return s.match("^[a-zA-Z\(\)]+$");
}
If memory serves this should work in javascript:
function containsOnlyLettersOrParenthesis(str)
(
return str.match(/^([a-z\(\)]+)$/i);
)
You could use Regular Expressions...
functions isLetter(str) {
return str.match("^[a-zA-Z()]+$");
}
Oops... my bad... this is wrong... it should be
functions isLetter(str) {
return "^[a-zA-Z()]+$".test(str);
}
As the other answer says... sorry