How to check if String ends with String - javascript

I'm trying to solve the following problem:
Complete the solution so that it returns true if the first argument (string) passed in ends with the 2nd argument (also a string).
Examples:
Solution ('abc', 'bc') // returns true,
solution ('abc', 'd') // returns false
Create a function that does this.
My code is:
function solution(str, ending){
return (str.split('').filter(str => str.length > str.length - 2).join('')) == ending ? "true" : "false"
}
The error I get:
expected 'false' to equal true

Some issues:
You have used the name str for the function parameter and for the parameter in the filter callback function. So in that callback function you'll have no access to the original str value.
In the filter callback, str will be a single character, so its length will always be 1. It makes no sense to compare it with anything
If you go with filter, then you'd want to do something with the index of the character, not the character itself.
In this problem the value 2 has no special meaning, it should not need to occur anywhere in your code
The function returns a string "true" or "false", but you are required to return a boolean value (true or false). Those are not strings.
Using the conditional (ternary) operator just to return a boolean is overkill: just return the boolean expression that serves for the condition.
The whole idea of using filter is not necessary as there is endsWith
I guess you wanted to do something like this:
function solution(str, ending){
return str.split('').filter((_, i) => i >= str.length - ending.length).join('') == ending ? true : false;
}
console.log(solution("longword", "word"));
But it can be as simple as:
function solution(str, ending){
return str.endsWith(ending);
}
console.log(solution("longword", "word"));

Related

Count Vowels in String Using Recursion With JavaScript

Hello I'm trying to understand recursion in JavaScript.
So far I have:
function countVowels(string) {
let vowelCount = 0;
// if we're not at the end of the string,
// and if the character in the string is a vowel
if (string.length - 1 >= 0 && charAt(string.length -1) === "aeiouAEIOU") {
//increase vowel count every time we iterate
countVowels(vowelCount++);
}
return vowelCount;
}
First of all, this is giving me issues because charAt is not defined. How else can I say "the character at the current index" while iterating?
I can't use a for-loop - I have to use recursion.
Second of all, am I using recursion correctly here?
countVowels(vowelCount++);
I'm trying to increase the vowel count every time the function is called.
Thanks for your guidance.
If you're interested, here is a version that does not keep track of the index or count, which might illuminate more about how the recursion can be done.
function countVowels(string) {
if (!string.length) return 0;
return (
"aeiou".includes(string.charAt(0).toLowerCase()) +
countVowels(string.substr(1))
);
}
console.log(countVowels("")); // 0
console.log(countVowels("abcde")); // 2
console.log(countVowels("eee")); // 3
// Note that:
console.log('"hello".substr(1)', "hello".substr(1)) // ello
console.log('"hello".charAt(0)', "hello".charAt(0)) // h
console.log('"aeiou".includes("a")', "aeiou".includes("a")) // true
console.log('"a".includes("aeiou")', "a".includes("aeiou")) // false
Our base case is that the string is empty, so we return 0.
Otherwise, we check if the first character in the string is a vowel (true == 1 and false == 0 in javascript) and sum that with counting the next (smaller by one) string.
You are making two mistakes:
You should have three parameters string , count(count of vowels) and current index i.
You should use includes() instead of comparing character with "aeiouAEIOU"
function countVowels(string,count= 0,i=0) {
if(!string[i]) return count
if("aeiou".includes(string[i].toLowerCase())) count++;
return countVowels(string,count,i+1);
}
console.log(countVowels("abcde")) //2
As asked by OP in comments "Can you please explain why it'sif("aeiou".includes(string[i].toLowerCase())) instead of if(string[i].includes("aeiou".toLowerCase()))"
So first we should know what includes does. includes() checks for string if it includes a certain substring passed to it or not. The string on which the method will be used it will be larger string and the value passed to includes() be smaller one.
Wrong one.
"a".includes('aeiou') //checking if 'aeiou' is present in string "a" //false
Correct one.
"aeiou".includes('a') //checking if 'a' is present in string "aeiou" //true
One possible solution would be:
function countVowels(string, number) {
if (!string) return number;
return countVowels(string.slice(1), 'aeiouAEIOU'.includes(string[0])? number + 1 : number);
}
// tests
console.log('abc --> ' + countVowels('abc', 0));
console.log('noor --> ' + countVowels('noor', 0));
console.log('hi --> ' + countVowels('hi', 0));
console.log('xyz --> ' + countVowels('xyz', 0));
and you should call your function like: countVowels('abc', 0)
Notes about your solution:
you always reset vowelCount inside your function, this usually does not work with recursion.
you defined your function to accept a string, but recall it with an integer in countVowels(vowelCount++); this it will misbehave.
always remember that you have to define your base case first thing in your recursion function, to make sure that you will stop sometime and not generate an infinite loop.
Alternative ES6 solution using regex and slice() method. Regex test() method will return true for vowels and as stated in a previous answer JavaScript considers true + true === 2.
const countVowels = str => {
return !str.length ? 0 : /[aeiou]/i.test(str[0]) + countVowels(str.slice(1));
}

Add empty string to first argument of parseInt

I'm just trying to understand how JS currying works. While I was looking for it I found a related example:
var add = function (orig) {
var inner = function (val) {
return add(parseInt(val+'', 10) == val ? inner.captured+val : inner.captured);
};
inner.captured = orig;
inner.valueOf = function () {return inner.captured;};
return inner;
};
What the point to add an empty string to the first argument in a parseInt
method?
I think it also can be related to the valueOf
val+'' converts expression to string.
Quick test to show what's going on:
typeof(1)
"number" // value is 1 (number)
typeof(1+'')
"string" // now value is "1" (a string)
what is the purpose of making it a string?
The purpose could be to avoid native code to call abstract ToString method to convert first argument of parseInt to string.
We can read in MDN that first argument to parseInt is string with following description:
The value to parse. If string is not a string, then it is converted to
a string (using the ToString abstract operation). Leading whitespace
in the string is ignored.
To explain we can re-write part of the code:
return add(parseInt(val+'', 10) == val ? inner.captured+val : inner.captured);
// could be written like:
if ( parseInt(val+'', 10) == val ) {
return inner.captured+val
}
else {
return inner.captured;
}
// Looking at:
parseInt(val+'', 10) == val
// we're checking if the number at base 10 is equal to itself
// parseInt takes a string as it's first parameter, hence
// the type-casting with +''.
// This step could probably be ignored as the docs say that the number is
// cast to a string automatically, however for completeness we might
// choose to manually cast it.
parseInt docs

JavaScript indexOf greater than -1 false when it's clearly not?

The value of the field with the id 'post_url' is http://www.example.com/. Shouldn't JavaScript return true for anything greater than -1?
alert('1a = '+id_('post_url').value.indexOf('http:'));// 0
alert('1b = '+id_('post_url').value.indexOf('http:') > -1);// false
alert('2a = '+id_('post_url').value.indexOf('www.'));// 7
alert('2b = '+id_('post_url').value.indexOf('www.') > -1);// false
You're comparing a string and a number. You're concatenating the result of indexOf (which I assume is -1) to a string before you do your > comparison. This is equivalent to NaN > -1.
"1b-1" > -1 // => false
Check Operator Precedence
The addition/string concatenation has greater precedence than relational comparison.
Your code needs some brackets/grouping operator to cure that:
alert( '1b = ' + ( id_('post_url').value.indexOf('http:')>-1 ) ); // 1b = true
You are attempting to evaluate a string concatenation as a number, which is returning false.
'2b'+id_('post_url').value.indexOf('www.')>-1
...using order of operations, will add the string, 2B to the index returned by, id_('post_url').value.indexOf('www.')
Thus, casting the entire thing as a string, and evaluating whether the string is greater than -1.
Here's how you need to write your alert.
alert(id_('post_url').value.indexOf('www.')>-1);
That should alert 'true'.
'2b'+id_('post_url').value.indexOf('www.')
You are adding 2b to index of, so it won't remain an integer but will have value as string of 2b+ whatever index you have. So that is the reason for what you are observing.

Integer validation not working as expected

Thanks to some of the answers on this site, I built a function to validate an integer inside a prompt in javascript. I found out how to use isNaN and the result of % in order to meet my needs, but there must be something wrong, because is still not working: This function for validation needs to accept only integers, and as extra bonus, it will also accept a special keyword used for a different purpose later on in the program.
So, previously I had defined:
var value = prompt("Type an integer");
So after that, I made a call for the validation function, and that included three conditions: The validation warning would jump if:
1) The string is not a number
2) The string % 1 is not 0 (means is not an integer)
3) The string is not the special keyword ("extra") which is also valid as input.
The function needs to loop and keep showing the prompt until a valid data is written.
while (isNaN(value) == true && value % 1 != 0 && value != "extra") {
alert("Please, type an integer");
var value = prompt("Type an integer");
}
What am I doing wrong? Thank you so much for any ideas. I know the integer validation has been asked many times here, and here I got a few ideas, but I might be missing something...
You might be complicating things too much... A quick regular expression will do the trick.
while (!/^(\d+|extra)$/i.test(value)) {
...
}
You typed only one equal at
isNaN(value) = true
jsFiddle example
var int = 10;
var str = "10";
var isInt = function(value) {
return (str === 'extra' || !isNaN(parseInt(value, 16)) || /^\d+$/.test(value));
};
var isIntStrict = function(value) {
return (isInt(value) && typeof value !== 'string');
}
console.log('false', isInt('kirk'));
console.log('true', isInt(int));
console.log('true', isInt(str));
console.log('true', 'strict - int', isIntStrict(int));
console.log('false','strict - string', isIntStrict(str));
console.log('false','strict - string', isIntStrict('0x04'));
console.log('true','strict - string', isIntStrict(0x04));
I assume that for your purposes #elclanrs' answer is all you need here, and is the simplest and most straightforward, but just for completeness and dubious laughs, I'm pretty sure that the following would also do what you're looking for:
function isAnIntOrExtra(v) {
if (parseInt(+v) === +v && v !== '') {
return parseInt(+v);
}
else if (v === 'extra') {
return v;
}
else {
return false;
}
}
Fiddle here
These should all pass and return an integer in decimal notation:
'387' returns 387
'-4' returns -4
'0' returns 0
'2.4e3' returns 2400
'0xf4' returns 244
while these should all fail:
'4.5' returns false
'2.4e-3' returns false
'0xgc' returns false
'' returns false
'seven' returns false
And the magic-word 'extra' returns 'extra'
Of course, it'll "fail" miserably with values like '1,345', and will probably roll right over octal notation, treating it as though it were decimal notation (depending on the JavaScript engine?), but it could be tweaked to handle those situations as well, but really, you're better off with the regex.

How do I compare string and boolean in Javascript?

I got the Json "false" from server. I respond as bool but it's Json so it's in browser type is String instead of bool.
So if I run (!data) whenever I want to check "false" == false then they not worked.
So how can I parse bool from String in JavaScript then?
"true" == true and "false" == false. Then the code (!data) can check what it is [true and false]
If one of the operands is a boolean, convert the boolean operand to 1 if it is true and +0 if it is false.
When comparing a number to a string, try to convert the string to a numeric value.
from MDN Equality Operators page
Examples:
true == "true"; // 1 == NaN → false
true == "1"; // 1 == 1 → true
false == "false"; // 0 == NaN → false
false == ""; // 0 == 0 → true
false == "0"; // 0 == 0 → true
I would just explicitly check for the string "true".
let data = value === "true";
Otherwise you could use JSON.parse() to convert it to a native JavaScript value, but it's a lot of overhead if you know it's only the strings "true" or "false" you will receive.
var data = true;
data === "true" //false
String(data) === "true" //true
This works fine.
Try expression data == "true"
Tests:
data = "false" -- value will be false
date = "true" -- value will be true
Also, fix your JSON. JSON can handle booleans just fine.
If its just a json "false"/"true", you can use,
if(! eval(data)){
// Case when false
}
It would be more cleaner, if you restrict the code to accept only JSON data from server, and always jsonParse or eval it to JS object (something like jquery getJSON does. It accepts only JSON responses and parse it to object before passing to callback function).
That way you'll not only get boolean as boolean-from-server, but it will retain all other datatypes as well, and you can then go for routine expressions statements rather than special ones.
Happy Coding.
I think you need to look at how the JSON data is being generated. You can definitely have a normal JS boolean false in JSON.
{ "value1" : false, "value2" : true }
String.prototype.revalue= function(){
if(/^(true|false|null|undefined|NaN)$/i.test(this)) return eval(this);
if(parseFloat(this)+''== this) return parseFloat(this);
return this;
}
From: http://www.webdeveloper.com/forum/showthread.php?t=147389
Actually, you just need the first "if" statement from the function -- tests to find true or false in the code and the evals it, turning it into the boolean value
if(data+''=='true'){
alert('true');
}
Convert boolean to string by appending with blank string. and then compare with Stringobject.

Categories