Getting undefined, and can't find the bug - javascript

I'm having trouble finding the bug in my program. The console.logs labelled "Debug 3" and "Debug 6" are both returning undefined. I'm sure it's obvious, but any help pointing them out would be much appreciated. I'm also still pretty new, so if you have any suggestions about a different way I should have done this, I'm open to the feedback!
I know I could have just written a bunch of if/else statements, but I really wanted to give an honest go at making the code modular, and as reusable as possible.
Side note: I know that my function/variable names are trash. I plan on renaming them all once the program is working properly. This was just easier to help keep track (though obviously that didn't work out very well, hence here I am).
The code I have so far is:
// ---------------------- INPUT CHECKS ---------------------- //
// Check and return the number of words supplied in the name
const checkNameLength = (name) => {
arr = name.split(' ');
return arr.length;
};
// Checks if the name contains any spaces on the edges
const checkForSpacesOnEdges = (name) => {
if (name[0] === ' ' || name[-1] === ' ') {
return true;
} else {
return false;
}
};
// Checks if the name contains an honorific
const checkIfContainsHonorific = (name) => {
let accumulator = 0;
let result;
for (let i = 0; i < name.length; i++) {
if (name[i] === '.') {
accumulator++;
}
}
if (accumulator !== 0) {
result = true;
} else {
result = false;
}
return result;
};
// Returns a 1 word string
const isSingleName = (name) => {
let result;
let arr = name.split(' ');
if (arr.length === 1) {
result = true;
} else {
result = false;
}
return result;
};
// ---------------------- OUTPUT ---------------------- //
// Return empty string
const emptyOutput = (name) => {
return 'empty string';
};
// Returns the exact string provided by user
const returnAsIs = (name) => {
return name;
};
// Returns the name with trailing spaces removed
const returnWithoutSpaces = (name) => {
return name.trim();
};
// Reverses the name string and returns it
const normalReverse = (name) => {
let arr = [];
let result;
arr = name.split(' ');
arr.reverse();
result = arr[0] + ', ' + arr[1];
result.toString();
return result;
};
// Reverses the first and last name, but leaves the honorific in front
const hasHonorificReverseNames = (name) => {
let arr = name.split(' ');
let firstAndLastArr = [];
for (let i = 1; i < arr.length; i++) {
firstAndLastArr.push(arr[i]);
}
firstAndLastArr.reverse();
return arr[0].toString() + firstAndLastArr[0].toString() + ', ' + firstAndLastArr[1].toString();
};
// Main func
const nameInverter = (name) => {
let result;
if (!name) {
result = emptyOutput(name);
} else if (isSingleName(name)) {
result = returnAsIs(name);
} else if (!checkIfContainsHonorific(name)) {
if (checkForSpacesOnEdges(name)) {
result = returnWithoutSpaces(name);
}
} else if (checkNameLength(name) === 1) {
if (checkIfContainsHonorific(name)) {
result = emptyOutput(name);
}
} else if (checkNameLength(name) === 2) {
console.log("Flag 1: ", name);
if (!checkIfContainsHonorific(name)) {
console.log("Flag 2: ", name);
result = name;
}
} else if (checkNameLength(name) === 2) {
if (checkIfContainsHonorific(name)) {
result = returnAsIs(name);
}
} else if (checkNameLength(name) === 3) {
if (checkIfContainsHonorific(name)) {
result = hasHonorificReverseNames(name);
}
} else {
return normalReverse(name);
}
return result;
};
console.log("Debug 1", nameInverter(''));
console.log("Debug 2", nameInverter('Ronald'));
console.log("Debug 3", nameInverter('Ronald McDonald'));
console.log("Debug 4", nameInverter(' Ronald McDonald '));
console.log("Debug 5", nameInverter('Dr. Ronald McDonald'));
console.log("Debug 6", nameInverter('Dr. Ron'));
The output that I'm getting from those console.logs (including the Flag 1 console.log in the function I suspected was causing problems, is listed below:
Debug 1 empty string
Debug 2 Ronald
Debug 3 undefined
Debug 4 Ronald McDonald
Debug 5 Dr.McDonald, Ronald
Flag 1: Dr. Ron
Debug 6 undefined
Thank you, any guidance is greatly appreciated!

So you're issue here is that you're actually reaching some of your if else statements, but then not setting the code within that code block.
Anytime you're getting undefined here, is because you're not setting result to anything.
if else statements won't 'fall through' so as soon as one is true, it will run that block of code, but not the following blocks.
A good example is with your 'debug 3' 'Ronald Mcdonald' check. It goes into your if else statements, and hits the has length === 2 test, but then in that code block, you do another test to see if it contains 'Dr.' and if it does then set result to name, but if this check fails, you're never setting result to the name.
Essentially you either need to order your if else statements so that they can be checked in order and they won't conflict or you need to nest additional if else statements within those checks for length to check for the other things that you want to.

Related

How Would I refactor this Depth First Search function to remove mutation [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 months ago.
Improve this question
So I'm currently working my way through an algorithms course and this was provided as the answer for the leetcode problem "Palindrome Partitioning". I would like to be able to refactor the code so that it does not mutate the answer array and instead returns it. Preferably there would be no separate dfs function, just one recursive function called partition. I'm normally decent at this kind of thing but I'm struggling with this one:
function partition(s) {
const ans = [];
const n = s.length;
function dfs(start, part) {
if (start == n) {
ans.push([...part]);
return;
}
for (let i = start + 1; i < n + 1; i++) {
const prefix = s.substring(start, i);
if (isPalindrome(prefix)) {
part.push(prefix);
dfs(i, part);
part.pop();
}
}
}
dfs(0, []);
return ans;
}
This is my attempt so far:
function partition(str, start) {
const result = [];
if (start == str.length) {
result.push([str]);
} else {
for (let i = start + 1; i < str.length; i++) {
const prefix = s.substring(start, i);
if (isPalindrome(prefix)) {
const results = partition(str, start + 1);
if (results.length) {
for (const r of results) {
result.push([prefix, ...r]);
}
} else {
result.push([prefix, s.substring(i + 1)]);
}
}
}
}
return result;
}
Your attempt needs a few corrections:
Spelling of s and str is not consistent
The start parameter needs a default value of 0
The recursive call is made with a wrong index. Not start + 1, but i
The base case should not place the whole string in an array. On the contrary that newly pushed array should be empty: result.push([]) or why not return [[]] immediately.
results.length will never be zero when coming back from recursion; the else block will never execute -- it can be omitted.
The for loop is making one iteration too few. The end condition should be i <= s.length
Here is the corrected version:
function partition(s, start=0) {
if (start == s.length) {
return [[]];
}
let result = [];
for (let i = start + 1; i <= s.length; i++) {
const prefix = s.slice(start, i);
if (isPalindrome(prefix)) {
for (const part of partition(s, i)) {
result.push([prefix, ...part]);
}
}
}
return result;
}
Note that this makes the solution a tad slower.
If you appreciate single-exit functions, you might also appreciate a (mutation-free) single-expression version:
const isPalindrome = (s) => s .split ('') .reverse () .join ('') == s
const palindromePartition = (s, i = 1, p = s .slice (0, i)) =>
s .length == 0
? [[]]
: i > s .length
? []
: [
... (isPalindrome (p) ? palindromePartition (s .slice (i)) .map (pp => [p, ...pp]) : []),
... (palindromePartition (s, i + 1))
]
console .log (palindromePartition ('aab'))
console .log (palindromePartition ('levelalevel'))
.as-console-wrapper {max-height: 100% !important; top: 0}
Here the body of our main function (so too the body of the isPalindrome helper) is a single expression. Developed independently from the original or trincot's refactoring, it mostly still expresses the same logic, just structures it differently.
Here are Trincot's answers modified to be single entry, single exit. For anyone wondering why someone would want to do this, or for the inevitable downvoting it will get by the early return brigade, I've provided an analogy and a diagram at the bottom.
function partition(str, start = 0) {
const result = [];
if (start != str.length) {
for (let i = start + 1; i <= str.length; i++) {
const prefix = str.slice(start, i);
if (isPalindrome(prefix)) {
const partitions = partition(str, i);
if (partitions.length == 0) {
result.push([prefix]);
} else {
for (const part of partitions) {
result.push([prefix, ...part]);
}
}
}
}
}
return result;
}
function partition(str, start = 0) {
const result = [];
if (start != str.length) {
for (let i = start + 1; i <= str.length; i++) {
const prefix = str.slice(start, i);
if (isPalindrome(prefix)) {
const partitions = partition(str, i);
for (const part of partitions) {
result.push([prefix, ...part]);
}
}
}
}
return result.length
? result
: [[]];
}
function partition(str, memo = {}) {
const result = [];
if (str) {
if (memo[str]) {
result.push(...memo[str])
} else {
for (let i = 1; i <= str.length; i++) {
const prefix = str.slice(0, i);
if (isPalindrome(prefix)) {
for (const part of partition(str.slice(i), memo)) {
result.push([prefix, ...part]);
}
}
}
memo[str] = result;
}
}
return result.length
? result
: [[]];
}
function partition(str, memo = {}) {
const result = [];
if (str) {
if (memo[str]) {
result.push(...memo[str]);
} else {
for (let i = 1; i <= str.length; i++) {
const prefix = str.slice(0, i);
if (isPalindrome(prefix)) {
const partitions = partition(str.slice(i), memo);
if (partitions.length == 0) {
result.push([prefix]);
} else {
for (const part of partitions) {
result.push([prefix, ...part]);
}
}
}
}
memo[str] = result;
}
} else {
result.push([]);
}
return result;
}
Structured Programming Hallway Analogy
Imagine you’re given a key and sent into a hallway. All along the hallway are locked doors to rooms and right at the end of the hallway is the exit.
As you come to a door along the hallway, you put your key in it and see if it opens. If it does, you enter the room. Inside the room there might be more doors. You try your key to see if any open. If they do, you walk inside and take a look around. Once you are finished in a room and there are no more doors to try you calmly walk back out to the hallway and out of the exit. This is structured programming.
Now imagine the same scenario. This time you come to a room in the hallway and the door unlocks. Great, you think, and walk straight in. Upon entering the room the door locks behind you, the floor caves in and you find yourself falling into darkness. You are being ejected from the building via a trap door. Congratulations, you have encountered an early return.
If you are working on a large codebase, the code you write will be worked on by people many years after you've departed the company. Which building would you rather explore? Which building do you want to leave for them?
Visually:

Javascript function that checks whether number is palindrome

I read through a few of palindrome questions posted here, but unfortunately couldn't find a way to fix mine. An example of what I'm trying to achieve:
Input: 989
Output: "It's a palindrome"
Input: 23
Output: "Not a palindrome"
Input: 9
Output: "It's a palindome" (any single digit)
My try
function Palindrome(num) {
let numToStringArray = num.toString().split('');
let reversedArray = numToStringArray.reverse();
if (num.toString().length<2) {
return "It's a palindrome"
}
else {
for (let i = 0; i<numToStringArray; i++;) {
if (numToStringArray[i] !== reversedArray[i]) {
return "It's not a palindrome"
}
else {
return "It's a palindrome"
}
}
}
}
When invoked, the function only works for single-digit strings. I tried to fix my for-loop, as I feel that the problem lies in the following line:
if (numToStringArray[i] !== reversedArray[i])
but could not come up with a working solution. Thanks for reading or even helping me out!
I'm spotting several problems...
First, you don't want a ; after your i++ in the loop definition. In jsFiddle at least, that's resulting in a syntax error. Other environments may be more forgiving, but it's worth fixing.
Second, the loop condition is wrong:
i < numToStringArray
should be:
i < numToStringArray.length
Third, the logic of the loop is a bit broken. You're returning "It's a palindrome" immediately if the very first pair match. So by that logic "1231" is a palindrome. Instead, only return within the loop if you find that it's not a palindrome. If the loop completes without returning, then return that it's a palindrome:
for (let i = 0; i < numToStringArray.length; i++) {
if (numToStringArray[i] !== reversedArray[i]) {
return "It's not a palindrome";
}
}
return "It's a palindrome";
Made this quick & working solution:
function checkPalindrome(num) {
var numString = num.toString();
return numString.split("").reverse().join("") == numString;
}
Provide an integer parameter inside the checkPalindrome() function, and it will return either true or false.
For example:
if (checkPalindrome(123321)) {
console.log("Is a palindrome");
} else {
console.log("Not a palindrome");
}
How about this
str === str.split('').reverse().join("")
like so
const palindrome = num => {
const str = num.toString();
return `It's ${str.length<2 || str === str.split('').reverse().join("") ? "" : "not "}a palindrome`
};
console.log(
[989, 23, 9].map(num => `${num}: ${palindrome(num)}`)
)
actually your numToStringArray is not reversing. Try this:
function Palindrome(num) {
let numToStringArray = num.toString().split('');
let reversedArray = num.toString().split('').reverse();
console.log("here", numToStringArray, reversedArray)
if (num.toString().length<2) {
return "It's a palindrome"
}
else {
for (let i = 0; i<numToStringArray.length; i++) {
if (numToStringArray[i] !== reversedArray[i]) {
return "It's not a palindrome"
}
else {
return "It's a palindrome"
}
}
}
}
console.log(Palindrome(686))
The reason your logic doesn't is mainly due to the fact that you use i < numToStringArray instead of i < numToStringArray.length as mentioned in the comments.
The simplest way to achieve what you want though, would simply be-
function isPalindrome(num) {
return num === Number(num.toString().split('').reverse().join(''));
}
This should work.
const pal = num => {
let reversedNum = parseFloat(num.toString().split('').reverse().join(''));
if (reversedNum === num) {
console.log("palindrome")
} else {
console.log("no palindrome")
}
}
pal(12121);
Without using split, reverse and join, it can be checked through a single array.
function Palindrome(num) {
let numToStringArray = num.toString();
var len = numToStringArray.length;
if (len < 2) {
return "It's a palindrome"
}
else {
for (var i = 0; i < len / 2; i++) {
if (numToStringArray[i] !== numToStringArray[len - 1 - i]) {
return "It's not a palindrome";
}
return "It's a palindrome"
}
}
}
console.log(Palindrome(989));
console.log(Palindrome(23));
console.log(Palindrome(9));
A short function to test if the number is a Palindrome and returns a "true" or "false" is as follows:
You can then call it and output your text result "It's a palindrome" in case it returns true or "Not a palindrome" if returns false.
Test examples provided below.
const IsPalindrome = e => (e+="").split("").reverse().join("") == e;
// ======== test =============
console.log(IsPalindrome(23)); // false
console.log(IsPalindrome(121)); // true
console.log(IsPalindrome(9889)); // true
console.log(IsPalindrome(989)); // true
console.log(IsPalindrome(1)); // true
To meet your specific requirements for the output text. Here is a one-liner function based on the function below:
function IsPalindrome(n) {
return n + (((n+="").split("").reverse().join("") == n) ? " is a palindrome" : " is not a palindrome");
}
// ======== test =============
console.log(IsPalindrome(23)); // 23 is not a palindrome
console.log(IsPalindrome(121)); // 121 is a palindrome
console.log(IsPalindrome(9889)); // 9889 is a palindrome
console.log(IsPalindrome(989)); // 989 is a palindrome
console.log(IsPalindrome(1)); // 1 is a palindrome
Taking advantage of its function, something you could do after using the split method and the reverse method to read the number from right to left, is to use the join to transform it into a string again and then compare them, like this:
function Palindrome(num) {
let numToStringArray = num.toString().split('');
let reversedArray = numToStringArray.reverse().join('');
if (num.toString() == reversedArray)
console.log('It\'s a palindrome');
else
console.log('It\'s not a palindrome');
}
Palindrome(9);
Palindrome(232);
Palindrome(152);
let a, b = 121;
a = b;
console.log(String(b).split("").reverse().join() === String(a).split("").join());

Find duplicates in array JavaScript

So I'm working on a simple JavaScript web-based game. The goal is to guess a X digit random number. This means the random number can be 4, 5 digits up to whatever you want. You can actually play the game at www.juegodescifralo.com , (it's in Spanish, sorry about that).
The user inputs a number that is stored as an array. The random number is also generated as an array. Individual numbers in both arrays can be repeated.
There are three types of possible "values/numbers": the "good" ones are the numbers you chose that are in the same position as the ones in the random array. So for example:
Random array is: 1457
User input is: 6851
Number 5 is a "good" number, since it's in the same position. Then there are the second type of "values", which are "regular". This means they are inside the random number but not in the same position. In this example, number 1 would be a "regular" value. And the third type is the "bad" ones, which are not even inside the random array.
The function I've developed is as follows:
function checkNumbers(randomArray, myArray, good, regular, bad) {
for (var x = 0; x < randomArray.length; x++) {
var posRepetido = randomArray.indexOf(myArray[x]); //Is current number inside random array?
if (posRepetido == -1) { //It's not inside
console.log("number " + myArray[x] + "is not inside");
bad++;
} else { //It's inside
regular++;
if (myArray[x] == randomArray[x]) { //If it's the same number...
console.log("number " + myArray[x] + "is in the correct position");
good++;
regular--;
} else { //If it's not the same number
if (randomArray[posRepetido] != myArray[posRepetido]) {
console.log("number " + myArray[x] + "is inside but not in the same position");
} else {
console.log("number " + myArray[x] + "is not inside");
}
}
}
}
var obj = { //Return object for accessing later, to show feedback to the user.
good: good,
regular: regular,
bad: bad
};
return obj;
}
The code is a bit buggy. When there are duplicates in the random array, and one of them is marked as good, then the other one (even if it exists in user input) will be set as bad, not as regular as it should.
The thing becomes even more complicated since you should be able to play against any amount of digits. So I should be able to guess a 20 digit number without "problems".
You can play by yourself at www.juegodescifralo.com
How can I go about this? Any ideas how can I access array data more easily? Thank you very much!
Rather than indexOf comparisons against -1 and checks of myArray[x], it would probably be a lot easier to use includes and array methods such as forEach for better abstraction. All you really need is an if, an else if, and an else. For example:
function checkNumbers(randomArray, userArray, good=0, regular=0, bad=0) {
userArray.forEach((guess, i) => {
if (guess === randomArray[i]) good++;
else if (randomArray.includes(guess)) regular++;
else bad++;
});
return { good, regular, bad };
}
// 4 good
console.log(checkNumbers(
'1234'.split(''),
'1234'.split(''),
));
// 4 good, 2 bad
console.log(checkNumbers(
'1234'.split(''),
'123456'.split(''),
));
// 4 good, 2 regular
console.log(checkNumbers(
'1234'.split(''),
'123412'.split(''),
));
// all regular:
console.log(checkNumbers(
'123456789123456789'.split(''),
'912345678912345678'.split(''),
));
i think it is easier to loop thru it twice like this
function checkNumbers(randomArray, guessArray) {
var clone = randomArray.slice(0);
var good = 0;
var regular = 0;
var bad = 0;
var visited = [];
guessArray.forEach(function(guess, index) {
if (guess === clone[index]) { // the guess is in right position
good++;
clone[index] = "x"; // strike it out so it cannot be used later
visited.push(index);
} else if (clone.indexOf(guess) === -1) {
bad++;
visited.push(index);
}
});
guessArray.forEach(function(guess, index) {
if (!visited.includes(index)) {
var match = clone.indexOf(guess);
if (match !== -1) {
regular++;
clone[match] = "x"; // strike it out so it cannot be used later
}
}
});
return {
good: good,
bad: bad,
regular: regular
}
}
first loop is to check the good and bad. and strikeout the value it is good so it cannot be used again.
second loop to check for the regular and strikeout the value it is used so it cannot be used again.
This should work.
function guessNumber (numUser, numRandom) {
if (typeof numUser == 'number') {
numUser = numUser.toString().split('');
}
if (typeof numRandom == 'number') {
numRandom = numRandom.toString().split('');
}
if (typeof numRandom != 'object' || typeof numUser != 'object') {
return false;
}
if (numRandom == numUser) {
return true;
}
var numRegular = {},
numBuenos = {},
numMalos = {},
numRepeat = {};
for(var i = 0; i < numRandom.length; i++) {
if (!numRepeat[numRandom[i]]) {
numRepeat[numRandom[i]] = 0;
}
numRegular[numRandom[i]] = 0;
numRepeat[numRandom[i]]++;
}
for (var i = 0; i < numUser.length; i++) {
if (numUser[i] == numRandom[i]) {
numBuenos[numUser[i]] = numUser[i];
}else if ($.inArray(numUser[i], numRandom)) {
if (!numRegular[numUser[i]]) {
numRegular[numUser[i]] = 0;
}
if (numRegular[numUser[i]] < numRepeat[numUser[i]]) {
numRegular[numUser[i]]++;
} else {
numMalos[numUser[i]] = numUser[i];
}
} else {
numMalos[numUser[i]] = numUser[i];
}
}
return {
regular: Object.values(numRegular).reduce((a, b) => a + b),
buenos: Object.keys(numBuenos).length,
malos: Object.keys(numMalos).length
};
}
console.log(guessNumber(8365, 8512));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

Check if second string is rotation of another string

I'm trying to write a function that takes in two string parameters and check if the second parameter is a rotated version of the first string.
So the following would be the results:
checkRotationStrings('waterbottle', 'lewaterbott'); // true
checkRotationStrings('waterbottle', 'bottlewater'); // true
checkRotationStrings('waterbottle', 'erbottlewat'); // true
checkRotationStrings('waterbottle', 'lewaterbottx'); // false
I wrote the following code, but there are some edge cases that I can't seem to figure out:
function checkRotationStrings(string, rotatedString) {
let result;
let rotationCheck
let stringArr = string.split('');
let rotatedStringArr = rotatedString.split('')
for (let i = 0; i < string.length - 1; i++) {
if (rotatedString[0] === stringArr[i]) {
result = stringArr.slice(i);
rotationCheck = stringArr.slice(0, i).concat(result).join('');
}
}
console.log(rotationCheck)
if (rotationCheck === string){
return true;
} else {
return false;
}
}
Any help would be appreciated.
You could use String#repeat with rotated and two as parameter and check with String#includes.
function checkRotationStrings(string, rotated) {
return string.length === rotated.length && rotated.repeat(2).includes(string);
}
console.log(checkRotationStrings('waterbottle', 'lewaterbott')); // true
console.log(checkRotationStrings('waterbottle', 'bottlewater')); // true
console.log(checkRotationStrings('waterbottle', 'erbottllewat')); // false
console.log(checkRotationStrings('waterbottle', 'lewaterbottx')); // false
console.log(checkRotationStrings('waterbottle', 'ttlewaterb')); // false
You could use substring and rotate until you find a match. Like this:
function checkRotationStrings(string, rotatedString) {
let match = false;
for (let i = 0;
(i < string.length - 1) & !match; i++) {
match = rotatedString.substring(i, rotatedString.length) + rotatedString.substring(0, i) === string;
}
return match
}
console.log(checkRotationStrings('waterbottle', 'lewaterbott')); // true
console.log(checkRotationStrings('waterbottle', 'bottlewater')); // true
console.log(checkRotationStrings('waterbottle', 'erbottlewat')); // true
console.log(checkRotationStrings('waterbottle', 'lewaterbottx')); // false
This is a somewhat strange solution, as it uses some only for the index parameter. But each iteration in some simply compares two strings, one which is a rotation of the first, and the other is the second one.
const checkRotationStrings = (str, rot) =>
str.split('').some((s, i) => str.slice(i) + str.slice(0, i) == rot);
[
['waterbottle', 'lewaterbott'], // true
['waterbottle', 'bottlewater'], // true
['waterbottle', 'erbottllewat'], // false -- ORIGINAL
['waterbottle', 'erbottlewat'], // true -- CORRECTED
['waterbottle', 'lewaterbottx'] // false
].forEach(([s, r]) => console.log(`'${s}', '${r}': ${checkRotationStrings(s, r)}`))
You can do the following:
checkRotationStrings(str1: string, str2: string) {
if (str1.length !== str2.length) {
return false;
} else {
for (var i = 0; i < str2.length; i++) {
if (str2[i] === str1[0]) {
var substring1 = str2.substring(0,i);
var substring2 = str2.substring(i,str2.length);
var concatWord = substring2.concat(substring1);
if(str1 === concatWord){
console.log(str1 + " matches " + concatWord)
return true;
}else{
console.log(str1 + " not matches " + concatWord)
}
}
}
return false;
}
}
Stack Overflow questions often receive answers in the form of completely new code (and/or ideas) on how to achieve the desired result. Usually, there's at least an attempt to help the questioner with their actual question, which in this case seemed to ask for some help with your code (one issue at least had to do with "slicing," as you commented).
I also love to offer new code or ideas if I particularly like it so I'm only partly critical here, but the answers so far have suffered from a complete lack of relating to the question.
There's nothing wrong with how you have conceived of checking for string rotation. You just have a couple of bugs:
First, since rotationCheck is meant to rotate string in order to compare it with rotatedString, you got the string-building reversed. It should be:
rotationCheck = result.concat(stringArr.slice(0, i)).join('');
Secondly, once you've built the rotation-check, you need to compare it with rotatedString, not string. So:
if (rotationCheck === rotatedString){
I might be late for this, but here is my solution and it include all edge cases.
function checkRotation(str1,str2){
const char0 = str1[0];
let ind = str2.indexOf(char0);
while(ind>-1){
const start = str2.substring(0,ind);
const end = str2.substring(ind,str2.length);
if(end+start === str1){
return true;
}
ind = str2.indexOf(char0,ind+1)
}
return false
}
console.log(checkRotation("assads","adsass"))
Instead of trying to break it in random pieces and do different checks, you could instead do a count of the letters. This would be much simpler:
const countLetters = a => Array.prototype.reduce.call(a, (r, l) => Object.assign(r, { [l]: (r[l] || 0) + 1 }), {});
function checkRotatedString(a, b) {
const countA = countLetters(a);
const countB = countLetters(b);
return Object.keys(countA).length === Object.keys(countB).length
&& Object.entries(countA).every(([key, value]) => value === countB[key]);
}
// Tests
[['waterbottle', 'lewaterbott'], ['waterbottle', 'bottlewater'], ['waterbottle', 'erbottlewat'], ['waterbottle', 'lewaterbottx']]
.forEach(a => console.log(a, checkRotatedString.apply(null, a)));

Check if a String is a Palindrome in JavaScript

The requirements for this task are that the code is returns a 'true' or 'false' for an input string. The string can be a simply word or a phrase. The other question does not address these needs. Please reopen and answer here. I am working on a function to check if a given string is a palindrome. My code seems to work for simple one-word palindromes but not for palindromes that feature capitalization or spaces.
function palindrome(str)
{
var palin = str.split("").reverse().join("");
if (palin === str){
return true;
} else {
return false;
}
}
palindrome("eye");//Succeeds
palindrome("Race car");//Fails
First the string is converted to lowercase. Also, the characters that are not the alphabet are removed. So the string comparison becomes a array, then invert it, and convert it to string again.
Step 1: str1.toLowerCase().replace(...) => "Race car" => "race car" => "racecar"
Step 2: str2.split("") => ["r","a","c","e","c","a","r"] => .reverse().join() => "racecar"
Result: str1 === str2
function palindrome(str) {
str = str.toLowerCase().replace(/[^a-z]+/g,"");
return str === str.split("").reverse().join("")
}
alert(palindrome("eye")); //true
alert(palindrome("Race car")); //true
alert(palindrome("Madam, I'm Adam")); //true
Something like if (word === word.split('').reverse().join('')) {/*its a palindrome!*/} I'd say
An isPalindrome String extention:
String.prototype.isPalindrome = function () {
var cleaned = this.toLowerCase().match(/[a-z]/gi).reverse();
return cleaned.join('') === cleaned.reverse().join('');
}
var result = document.querySelector('#result');
result.textContent = "'eye'.isPalindrome() => " + 'eye'.isPalindrome() +
"\n'Something'.isPalindrome() => " + 'Something'.isPalindrome() +
"\n'Race Car'.isPalindrome() => " + 'Race Car'.isPalindrome() +
"\n'Are we not drawn onward, we few, drawn onward to new era?'.isPalindrome() => " +
'Are we not drawn onward, we few, drawn onward to new era?'.isPalindrome() +
"\n'Never even or odd'.isPalindrome() => " + 'Never even or odd'.isPalindrome() +
"\n'Never odd or even'.isPalindrome() => " + 'Never odd or even'.isPalindrome();
;
<pre id="result"></pre>
function palindrome(str) {
let letters = str.split('').filter(function (str) {
return /\S/.test(str);
});
let reversedLetters = str.split('').reverse().filter(function (str) {
return /\S/.test(str);
});
for (let i = 0; i < letters.length; i++) {
if (letters[i].toLowerCase() !== reversedLetters[i].toLowerCase()) {
return false;
}
}
return true;
}
console.log(palindrome("eye")); //true
console.log(palindrome('Race car')); //true
const palindromes = arrayOfWords.filter((item) => {
return item === item.split('').reverse().join('');
})
This is an example :-)
function palindrome(str) {
var st='';
st=str.replace(/[^a-z0-9]/ig,"").toLowerCase();
var arr=[];
arr=st.split('');
arr=arr.reverse();
var strr='';
strr=arr.join('');
if(strr==st) {
return true;
}
return false;
}
palindrome("A man, a plan, a canal. Panama");//calling the function
//1. change the string to an array
//2. use the reverse method
//3. return the array as a string
//4. return input= new reversed string
var lowerCasedString = inputString.toLowerCase();
var reversedString = lowerCasedString.split("").reverse().join("");
return reversedString === lowerCasedString;
}hope this would be helpful:
Palindrome using ES6
const checkPalindrome=(str)=> {
return str.toLowerCase().trim() === str.toLowerCase().trim().split('').reverse().join('');
}
console.log(checkPalindrome("Level "))
As easy as possible!
function checkStrForPalindorme(string) {
const str = string.toLowerCase().trim();
const reversedStr = str.split("").reverse().join("");
return str === reversedStr;
}
console.log(checkStrForPalindorme("aaffaa "))
console.log(checkStrForPalindorme("dummy"))
I have created a lookup object first and then analyze the frequency of each lookup item
if the str = "PEEPs", then
lookUp = {p:2, e:2, s:1}
Please refer to the following function for more details
function checkPlaindrome(str) {
const lookUp = {};
// Create the lookUp object
for (let char of str.toLowerCase().trim()) {
if (char !== " ") lookUp[char] = ++lookUp[char] || 1;
}
// Analyse the lookup object
const singleCharCheck = Object.values(lookUp).filter((val) => val === 1);
const findalSingleCharCheck =
singleCharCheck.length === 0 || singleCharCheck.length === 1;
const noneSingleCharCheck =
Object.values(lookUp)
.filter((val) => val !== 1)
.filter((val) => val % 2 !== 0).length === 0;
return findalSingleCharCheck && noneSingleCharCheck;
}
const r = checkPlaindrome("w wPEEPs"); // true
const r1 = checkPlaindrome("w PEEPs"); // false

Categories

Resources