I am a newbie who is trying hard to have a grip on javascript. please help me to consolidate my fundamentals.
input will be a string of letters.
following are the requirements.
function should return true if following conditions satisfy:
letters are in alphabetical order. (case insensitive)
only one letter is passed as input. example :
isAlphabet ('abc') === true
isAlphabet ('aBc') === true
isAlphabet ('a') === true
isAlphabet ('mnoprqst') === false
isAlphabet ('') === false
isAlphabet ('tt') === false
function isAlphabet(letters) {
const string = letters.toLowerCase();
for (let i = 0; i < string.length; i++) {
const diff = string.charCodeAt(i + 1) - string.charCodeAt(i);
if (diff === 1) {
continue;
} else if (string === '') {
return false;
} else if (string.length === 1) {
return true;
} else {
return false;
}
}
return true;
}
It's generally a better practice to start your function off with dealing with the edge-cases rather than putting them somewhere in the middle. That way, the function returns as soon as it can - and it's a lot easier to read than a waterfall of if..else statements.
function isAlphabet(letters) {
if ("" == letters) {
return false;
}
if (1 == letters.length) {
return true;
}
const string = letters.toLowerCase();
// carry on with your loop here.
}
You've got the right idea, but it can be simplified to just fail on a particular error condition, i.e when a smaller character follows a larger one:
function isAlphabet(letters) {
const string = letters.toLowerCase();
let lastChar;
for (let i = 0; i < string.length; i++) {
// Grab a character
let thisChar = string.charCodeAt(i);
// Check for the failure case, when a lower character follows a higher one
if (i && (thisChar < lastChar)) {
return false;
}
// Store this character to check the next one
lastChar = thisChar;
}
// If it got this far then input is valid
return true;
}
console.log(isAlphabet("abc"));
console.log(isAlphabet("aBc"));
console.log(isAlphabet("acb"));
You can use the simple way to achieve the same as below
function isAlphabet(inputString)
{
var sortedString = inputString.toLowerCase().split("").sort().join("");
return sortedString == inputString.toLowerCase();
}
console.log("abc = " + isAlphabet("abc"));
console.log("aBc = " + isAlphabet("aBc"));
console.log("acb = " + isAlphabet("acb"));
console.log("mnoprqst = " + isAlphabet("mnoprqst"));
Note: Mark the answer is resolves your problem.
Related
I am trying to make a palindrome checker with the condition of having to use a while loop.
It's giving me a right headache!
it returns isPalindrome as false every time even if the word is a palindrome.
let word = prompt('Please Enter a word')
let reverse = word.split('').reverse().join('').toLowerCase();
i = 0
final = word.length
let isPalindrome = false
while (i < word.length) {
if(word[i] == reverse[i])
i++
if(i = word.length)
break;
else if (i !== word.length)
break;
}
if (i == word.length) {
isPalindrome == true
}
else if (true) {
isPalindrome == false
}
if (isPalindrome == true) {
window.alert('Your word is a palindrome')
}
else if (isPalindrome == false) {
window.alert('Your word is not a palindrome')
}
I have tried messing around with the == signs and changing the break;
it used to return as always palindrome, but now it always returns as not a palindrome
The idea is to compare the word with the reverse version of it and check every index to see if it matches.
If they all match the word is a palindrome (racecar && racecar)
If they do not match it is not (racer && recar)
The program should output the result
Many thanks!
Alternative: nibble off letters of the word from both sides and compare them until either there's one letter left (is palindrome) or they don't match (no palindrome):
const isPalindrome = word => {
const letters = word.toLowerCase().split("");
while (letters.length > 1) {
if (letters.shift() !== letters.pop()) {
// not a palindrome: break the loop
// by returning false
return false;
};
}
return true;
}
console.log(`racecar ${isPalindrome(`racecar`)}`);
console.log(`rotator ${isPalindrome(`rotator`)}`);
console.log(`carrace ${isPalindrome(`carrace`)}`);
console.log(`rotonda ${isPalindrome(`rotonda`)}`);
I am looking at this code challenge:
Complete the function isAllX to determine if the entire string is made of lower-case x or upper-case X. Return true if they are, false if not.
Examples:
isAllX("Xx"); // true
isAllX("xAbX"); // false
Below is my answer, but it is wrong. I want "false" for the complete string if any of the character is not "x" or "X":
function isAllX(string) {
for (let i = 0; i < string.length; i++) {
if (string[i] === "x" || string[i] === "X") {
console.log(true);
} else if (string[i] !== "x" || string[i] !== "X") {
console.log(false);
}
}
}
isAllX("xAbX");
Your loop is outputting a result in every iteration. There are two issues with that:
You should only give one result for an input, so not in every iteration; currently you are reporting on every single character in the input string.
You are asked to return a boolean result (false/true), not to have the function print something. That should be left to the caller
You could take a simpler approach though, and first turn the input string to all lower case. Now you only have to look for "x". Then take out all "x" and see if something is left over. You can check the length property of the resulting string to decide whether the return value should be false or true:
function isAllX(string) {
return string.toLowerCase().replaceAll("x", "").length == 0;
}
console.log(isAllX("xxXXxxAxx")); // false
console.log(isAllX("xxXXxxXxx")); // true
If you are confortable with regular expressions, you could also use the test method:
function isAllX(string) {
return /^x*$/i.test(string);
}
console.log(isAllX("xxXXxxAxx")); // false
console.log(isAllX("xxXXxxXxx")); // true
You can try this way.
function isAllX(str) {
let isX = true;
let newString = str.toLowerCase();
for (let i = 0; i < newString.length; i++) {
if (newString[i] !== "x") {
isX = false;
}
}
return isX;
}
console.log(isAllX("xAbX"));
console.log(isAllX("XXXxxxXXXxxx"));
You can use regex to find the same.
function allX(testString) {
return /^x+$/i.test(testString);
}
console.log(allX("xxXX"));
console.log(allX("xxAAAXX"));
Without any method if you want
function isAllX(str) {
let flag = true;
for (let i = 0; i < str.length; i++) {
if (str[i] !== "x" && str[i] !== "X") {
flag = false;
// break;
}
}
return flag;
}
console.log(isAllX("xAbX"));
console.log(isAllX("XXXxxxXXXxxx"));
console.log(isAllX("xx"));
You can try converting the string to a single case, then looping over it while checking for the condition as below
function isAllX(string) {
const newString = string.toUpperCase();
for (let i = 0; i < newString.length; i++) {
if (newString[i] !== "X") {
return false
}
}return true
}
So this is my code below, the goal is for this program is to check to see if the letters of the second string can be found in the first string. However I found the problem that i isn't, increasing in value. So the loop is only going through once. So this program ends at the first letter that it finds and returns true. How do I get i to increase so that it's iterating through every character of the string?
function mutation(arr) {
var str = arr[1];
str = str.toLowerCase().split("");
var i = 0;
while (i < arr.length) {
if (arr[0].indexOf(str[i]) > -1) {
//return arr[i].indexOf(str[i], i);
return true;
} else {
return false;
}
i++;
}
}
mutation(["hello", "hey"]);
This maybe?
function mutation(arr) {
var str = arr[1];
str = str.toLowerCase().split("");
// iterating an array screams "for loop"
for (var i=0; i < str.length; i++) {
// if the letter was not found exit immediately
if (arr[0].indexOf(str[i]) == -1) return false;
}
// since it didn't exit before, all the letters must have been found.
return true;
}
function mutation(arr) {
var base = arr[0],
str = arr[1].toLowerCase().split(''),
i = 0,
match = true;
while (i < str.length) {
// if any target letter is not in base, return false
if(base.indexOf(str[i]) === -1){
return false;
}
}
// otherwise they were all in, so return true
return true;
}
mutation(["hello", "hey"]);
Totally different technique.
This function replaces, in the second string, all letters from the first string with empty space. If the length is zero all letters were found.
function mutation(arr) {
return arr[1].replace(new RegExp("[" + arr[0] + "]", "g"), "").length == 0;
}
The Function to check mathematical expression not working.
I debugged this on chrome, and i saw that when it gets to the first pop (stack.pop()!== chars[i]), it returns false, but it shouldn't.
var smarter_validate = function(str) {
var chars = str.split('');
var stack = [];
var lookup = {
'(': ')',
'[': ']',
'{': '}',
'<': '>'
};
var left = Object.keys(lookup);
var right = Object.keys(lookup).map(function(key) {
return lookup[key]
});
for (var i = 0; i < chars.length; i++) {
if (left.indexOf(chars[i]) !== (-1)) {
stack.push(chars[i]);
} else if (right.indexOf(chars[i]) !== (-1)) {
if ((stack.length === 0) || (stack.pop() !== chars[i])) {
return false;
}
}
}
return (stack.length === 0);
};
console.log("SMART VALIDATE" + smarter_validate('(3+4[*2{6+8}])'));
You actually have to compare the popped value's corresponding closing character with chars[i], not the popped value itself.
So you need to do
if (stack.length === 0 || lookup[stack.pop()] !== chars[i]) {
Now, when you { from the stack, you will look for the corresponding closing character from the lookup and compare it with the current closing character.
Alternatively you can simply push the expected closing character in the stack so that you don't have do the lookup during the comparison, like this
stack.push(lookup[chars[i]]);
I'm trying to see if the string in the first element of the array contains all of the letters of the string in the second element of the array.
For example
['hello', 'hey'] = false;
['Army', 'Mary'] = true;
Here is my code
function mutation(arr) {
a = arr[0].toLowerCase().split("");
b = arr[1].toLowerCase().split("");
for(i = 0; i < a.length; i++){
if(b.indexOf(a[i]) != -1){
console.log('true');
} else {
console.log('false');
}
}
}
mutation(['Army', 'Mary']);
UPDATED
I need to see if element 1 contains all the letters for element 2 before I return back anything.
This would do, I'm sure there are better and optimal solutions though,
1) Storing the return result in a boolean, as var result = true;.
2) Check if both the Strings are equal/same, no need to loop, return the result which is true.
3) loop through each characters and see if the target element contains them, if found a mismatch set, result to false, break and return result.
function mutation(arr) {
a = arr[0].toLowerCase().split("");
b = arr[1].toLowerCase().split("");
var result = true;
if(a === b)
return result;
for(i = 0; i < a.length; i++){
if(b.indexOf(a[i]) === -1){
result = false;
break;
}
}
return result;
}
mutation(['Army', 'Mary']);
UPDATE Added a condition if (a === b) return true; to skip for loop.
No need of loop, you can take advantage of array functions.
Steps
Sort both arrays
Cast to the string
Check if strings2 contains string1
function mutation(arr) {
var a = arr[0].toLowerCase().split(''),
b = arr[1].toLowerCase().split('');
// For exact equality
return a.sort().toString() === b.sort().toString();
// return b.sort().toString().indexOf(a.sort().toString()) > -1;
}
document.write('Army and Mary: ' + mutation(['Army', 'Mary'])); // true
document.write('<br />a and b: ' + mutation(['a', 'b'])); // false
document.write('<br />ab and abc: ' + mutation(['ab', 'abc'])); // false
Simply you need to loop throught the second element letters and return false if a character doesn't exist in first element, or continue the loop if it exists.
Then check if the counter is equal to your string length then it contains all the given letters and return true:
function mutation(arr) {
a = arr[1].toLowerCase().split("");
b = arr[0].toLowerCase().split("");
if (a === b) return true;
for (i = 0; i < a.length; i++) {
if (b.indexOf(a[i]) === -1) {
return false;
}
}
if (i === a.length) {
return true; // all the letteers of element one exists in the second element
}
}
if (mutation(['Army', 'Mary'])) {
alert("Element one contains all letters of second element !");
} else {
alert("Sorry!");
}
Note:
Make sure you loop throught the second element characters and not the first one, see the a = arr[1].toLowerCase().split("");.
//mutation function work ignoring case and order of character in strings
function mutation(arr) {
var first = arr[0].toLowerCase();
var second = arr[1].toLowerCase();
for(var i = 0; i < second.length; i++){
if(first.indexOf(second[i]) == -1){
return false;
}
}
return true;
}
//this returns true
mutation(["hello", "ol"]);