I was trying to solve a code wars kata called "Check same case", and I'm not understanding what is wrong with my solution and why it doesn't pass.
The function should check:
If either of the characters is not a letter, return -1
If both characters are the same case, return 1
If both characters are letters, but not the same case, return 0
Here's my solution:
function sameCase(a, b) {
if (!a.match(/[A-z]/g) || !b.match(/[A-z]/g)) {
return -1
} else if ((a.match(/[A-Z]/g) && b.match(/[A-Z]/g)) || (a.match(/[a-z]/g) && b.match(/[a-z]/g))) {
return 1
} else {
return 0
}
}
The solution passes in all the tests, but when I click on "Attempt" I get these two errors:
For sameCase("^","B"): expected 0 to equal -1
function sameCase(a, b) {
if (!a.match(/[A-z]/g) || !b.match(/[A-z]/g)) {
return -1
} else if ((a.match(/[A-Z]/g) && b.match(/[A-Z]/g)) || (a.match(/[a-z]/g) && b.match(/[a-z]/g))) {
return 1
} else {
return 0
}
}
console.log(sameCase("^", "B"));
For sameCase("]","D"): expected 0 to equal -1
function sameCase(a, b) {
if (!a.match(/[A-z]/g) || !b.match(/[A-z]/g)) {
return -1
} else if ((a.match(/[A-Z]/g) && b.match(/[A-Z]/g)) || (a.match(/[a-z]/g) && b.match(/[a-z]/g))) {
return 1
} else {
return 0
}
}
console.log(sameCase("]", "D"));
As anticipated in the comments, your solution fails the tests because the range you use in your RegExp ([A-z] = from char code 65 to char code 122) includes also some non-alphabetic characters, such as the ones used in the tests: ] (char code 93) and ^ (char code 94).
That said, your solution presents also another issue as you are not checking that the arguments passed to the function are single characters rather than strings. In fact:
function sameCase(a, b) {
if (!a.match(/[A-z]/g) || !b.match(/[A-z]/g)) {
return -1
} else if ((a.match(/[A-Z]/g) && b.match(/[A-Z]/g)) || (a.match(/[a-z]/g) && b.match(/[a-z]/g))) {
return 1
} else {
return 0
}
}
console.log(sameCase("0123A", "A4567")); // will return 1 because the only letter of both string is in the same case
Solution
You can solve both issues simply by tuning the RegExp:
function sameCase(a, b) {
if (!a.match(/^[A-Za-z]$/) || !b.match(/^[A-Za-z]$/)) {
return -1
} else if (
(a.match(/^[A-Z]$/) && b.match(/^[A-Z]$/)) ||
(a.match(/^[a-z]$/) && b.match(/^[a-z]$/))
) {
return 1
} else {
return 0
}
}
console.log(sameCase('D', ']'));
console.log(sameCase('D', '^'));
console.log(sameCase('0123A', 'A4567'));
Although in a case like this I would tend to use RegExp.prototype.test(), which returns a boolean, because there is no real use for the array returned by String.prototype.match():
function sameCase(a, b) {
if (!/^[A-Za-z]$/.test(a) || !/^[A-Za-z]$/.test(b)) {
return -1
} else if (
(/^[A-Z]$/.test(a) && /^[A-Z]$/.test(b)) ||
(/^[a-z]$/.test(a) && /^[a-z]$/.test(b))
) {
return 1
} else {
return 0
}
}
console.log(sameCase('D', ']'));
console.log(sameCase('D', '^'));
console.log(sameCase('0123A', 'A4567'));
[A-Za-z] will check that the sub-strings contain only Latin letters and the use of ^ and $ to indicate the beginning and the ending of the string will check that they are only one character each.
Note
Please ignore my comment about the use of String.prototype.charCodeAt(), as I misread the requirements and assumed the function had to check whether the two arguments were the same letter in the same case... and even in that case, you could check it with a strict equality operator (a === b) with no need to over-complicate it with charCodeAt(). I do not really know what I was thinking. :P
Related
I'm trying to write a function that checks a string for multiple conditions. However, I have reached a wall when trying to figure out how to check if the first character in a string is a letter only.
function SearchingChallenge(str) {
// code goes here
let onlyLetters = /^[a-zA-Z]+$/;
if (str.length > 4 && str.length < 25){
if (onlyLetters.test(str)){
return true;
} else {
return false;
}
} else {
return false;
}
}
"u__adced_123" should return true but it's returning false. I've tried str[0]==onlyLetters but still the same.
onlyLetters.test(str) checks the whole string. To get the first character, use str.charAt(0).
function SearchingChallenge(str) {
let onlyLetters = /^[a-zA-Z]+$/;
if (str.length > 4 && str.length < 25) {
if (onlyLetters.test(str.charAt(0))) {
return true;
} else {
return false;
}
} else {
return false;
}
}
console.log(SearchingChallenge('Hello World!'));
console.log(SearchingChallenge('!dlroW olleH'));
console.log(SearchingChallenge('u__adced_123'));
const SearchingChallenge = str => (
!!str[4] && // > 4
!str[24] && // < 25
(/^[a-z]+$/i).test(str) // alpha
);
// Tests...
// true: greater than four characters
console.log(SearchingChallenge('Fiver'));
// true: less than twenty-five characters
console.log(SearchingChallenge('TwentyFouroooooooooooooo'));
// false: twenty-five or more characters
console.log(SearchingChallenge('TwentyFiveooooooooooooooo'));
// false: contains numbers
console.log(SearchingChallenge('abcd1234'));
// false: less than five characters
console.log(SearchingChallenge('Four'));
I want return true if the number is an integer with 4 or 6 digits. no decimals or letter allowed
The thing is not working is the if its really a number check and if its got a decimal.
i think i got already the right functions applied to it but i just cant connect them properly to my if statement.
so i want to check if 3 different things a true then return true but didnt figured out
Please if possible only answer with a hint or a link or SUDO Code or stuff i can look up.
gonna answer the question myself when i figured it out
JS
function validatePIN (pin) {
//return true or false
var result = (pin - Math.floor(pin)) !== 0;
if( pin.length === 4 || isNaN(pin) || result) {
return true
} else if ( pin.length === 6 || isNaN(pin) || result) {
return true
} else return false
}
Thanks
A simple regular expression can be used to test that is is 4 or 6 numbers.
function isValidPin (pin) {
return /^(\d{4}|\d{6})$/.test(pin.toString());
}
console.log(isValidPin(123));
console.log(isValidPin("1234"));
console.log(isValidPin("12345"));
console.log(isValidPin("123456"));
console.log(isValidPin("1234567"));
console.log(isValidPin("12.45"));
console.log(isValidPin("12e45"));
You can check the conditions with the AND operator (&&).
function validatePIN (pin) {
//return true or false
var result = (pin - Math.floor(pin)) !== 0;
if( pin.length === 4 && isNaN(pin) && result)
{ return true} else if ( pin.length === 6 && isNaN(pin) && result) {
return true
} else return false
}
You need to change your or to and
function validatePIN (pin) {
//return true or false
var result = (pin - Math.floor(pin)) !== 0;
if( pin.length === 4 && isNaN(pin) && result)
{ return true}
else if ( pin.length === 6 && isNaN(pin) && result) {
return true
} else return false
}
Ty this:
function validatePIN(pin) {
var parsed = Math.parseInt(pin, 10);
// if it's not an integer
if(pin !== parsed.toString()) return false;
return pin.length === 4 || pin.length === 6;
}
perhaps I'm mistaken - but you could just check if the length is 4 OR 6, and continue your other two checks:
function validatePIN (pin) {
//return true or false
var result = (pin - Math.floor(pin)) !== 0;
if(!isNaN(pin) && (pin.length === 4 || pin.length === 6) && result) {
return true
} else return false
}
I've also edited your code, as it seemed illogical returning true for NaN.
I think you want this. You should use regular expression for simplicity.
console.log(445584, validatePin(445584));
console.log("445584", validatePin("445584"));
console.log("alj454", validatePin("alj454"));
console.log(4455.84, validatePin(4455.84));
function validatePin(pin){
return /^(\d{4}|\d{6})$/.test(pin);
}
You might want to look into using isNaN() to detect if there are any characters that aren't numbers.
Also, using .toString() so you can check the .length.
I was trying to solve the following coding exercise.
We have two special characters. The first character can be represented
by one bit 0. The second character can be represented by two bits (10
or 11).
Now given a string represented by several bits. Return whether the
last character must be a one-bit character or not. The given string
will always end with a zero.
example:
Input: bits = [1, 0, 0] Output: True
Below is my solution for the above challenge. Why is this returning undefined? If I use [1,0,1,0] as input, it should return true but I am getting undefined. I am explicitly writing true in the return statement and not the results of a variable.
var isOneBitCharacter = function(bits) {
console.log(bits);
var length = bits.length;
if (length == 1) {
return true;
}
if (length == 0) {return false;}
if (length == 2 && bits[0] === 1) {
return false;
}
if (bits[0] === 1) {
isOneBitCharacter(bits.slice(1));
} else {
isOneBitCharacter(bits.slice(2));
}
};
isOneBitCharacter([1,0,1,0]);
I guess you are missing returns. Here is adjusted code:
var isOneBitCharacter = function(bits) {
console.log(bits);
var length = bits.length;
if (length == 1) {
return true;
}
if (length == 0) {return false;}
// added return here and next statements
if (length == 2 && bits[0] === 1) {
return false;
}
if (bits[0] === 1) {
return isOneBitCharacter(bits.slice(1));
} else {
return isOneBitCharacter(bits.slice(2));
}
};
isOneBitCharacter([1,0,1,0]);
I am trying to create a function pluralizeParam(n, word, pluralWord) with these requirements:
If n is 1, return the non-plural word (parameter word);otherwise, add an āsā to the plural word;
If the pluralWord parameter is provided, instead of adding an ās,ā return the pluralWord.
What I have done so far is following:
function returnPluralWord(n, word, pluralWord) {
if (n === 1) {
return word;
} else if (n === 1 && (word.lastIndexOf("s")) || (word.lastIndexOf("ess"))) {
return word + "s";
} else if (n !== 1 && word.length - 2 === "es") {
return word + "s";
} else if (pluralWord !== 'undefined') {
return pluralWord;
}
}
var result = returnPluralWord(2, "lioness", "lionesses");
console.log(result);
My problem is: it is not printing pluralWord. How do I do that?
Thanks
word.length - 2 can't never be equal to "es". You need also to rearrange your statements, the 2nd is already catched by 1.
When you use the word.lastIndexOf('s') ( which is wrong logic I think ), it returns the last index of the s character, not if it ends on s.
You can check String#endsWith and String#startsWith methods, these ones check if the string starts or ends with the given part
const str = 'less';
console.log(str.endsWith('s'))
In a web application, how do I determine whether the first letter in a given string is upper- or lower-case using JavaScript?
You can use toUpperCase:
if(yourString.charAt(0) === yourString.charAt(0).toUpperCase()) {
//Uppercase!
}
If you're going to be using this on a regular basis, I would suggest putting it in a function on the String prototype, something like this:
String.prototype.isFirstCapital = function() {
return this.charAt(0) === this.charAt(0).toUpperCase();
}
if(yourString.isFirstCapital()) {
//Uppercase!
}
Update (based on comments)
I don't know what you actually want to do in the case that the string does not being with a letter, but a simple solution would be to add a quick check to see if it does or not, and return false if not:
String.prototype.isFirstCapital = function() {
return /^[a-z]/i.test(this) && this.charAt(0) === this.charAt(0).toUpperCase();
}
This will work only with English alphabet.
var ch = myStr.chatAt(0);
if (ch >= 'a' && ch <= 'z') {
// small
} else if (ch >= 'A' && ch <= 'Z') {
// capital
} else {
// not english alphabet char
}
var mystring = "Test string";
var first= "";
if (mystring )
{
first= mystring[1];
}
if (first)
{
$('p').each(function()
{
if ($(this).text().charAt(0).toUpperCase() === $(this).text().charAt(0))
{
alert("Uppercase");
}
});
}
This will be called recursively until a first letter in a string is approached, otherwise returns 'no letters'.
function getFirstCase(string) {
if (string === '') return 'no letters';
var firstChar = string.charAt(0);
/*
* If both lowercase and uppercase
* are equal, it is not a letter
*/
if (firstChar.toLowerCase() === firstChar.toUpperCase()) {
return getFirstCase(string.substr(1));
} else {
return firstChar.toLowerCase() === firstChar ? 'lowercase' : 'uppercase';
}
}
Testing:
console.log(getFirstCase('alphabet'),
getFirstCase('Sunshine'),
getFirstCase('123123'),
getFirstCase('#Hi'),
getFirstCase('\nHAHA'));
I'm surprised no one's offered a regex solution to this - it seems like the easiest by far:
function getFirstCase(s) {
return (/^[\d\W]*[A-Z]/).test(s) ? 'upper' :
(/^[\d\W]*[a-z]/).test(s) ? 'lower' :
'none';
}
Blatantly stealing #Lapple's test cases:
console.log(getFirstCase('alphabet'),
getFirstCase('Sunshine'),
getFirstCase('123123'),
getFirstCase('#Hi'),
getFirstCase('\nHAHA'));
// lower upper none upper upper
See http://jsfiddle.net/nrabinowitz/a5cQa/