indexOf gives false positives - javascript

I made a function to search words in a string given. The function called str_find receives the word and then the parameters to search. These parameters can be an array with strings or only a string.
For example, if I call the function like: str_find("123456789&", ["", "123456789&"]); it should give me true, but for a rare reason sometimes it gives me false.
Can you help me please?
My code:
function str_find(word, find){
if(!Array.isArray(find)){
if (word.indexOf(find) > 0) {
return true;
} else {
return false;
}
} else {
var flag = false;
for (var i = 0, length = find.length; i < length; i++) {
if (word.indexOf(find[i]) > 0) {
flag = true;
break;
}
}
return flag;
}
}

You can take advantage of both String and Array having an includes() prototype method
function str_find(needle, haystack) {
return haystack.includes(needle);
}
console.log(str_find("123456789&", ["", "123456789&"]))
console.log(str_find("foo", 'foobar'))

MDN points out the reason in an obscure way:
Return value
The value of the first element in the array that satisfies the
provided testing function. Otherwise, undefined is returned.
When the string is found at the very first position of the searched string, it returns a found location index of 0 - which is a falsy value:
Thus your logical test if (word.indexOf(find) > 0) returns false when this occurs and gives the false indication that the string was not found, when in fact it was found at the very beginning of the search string.
You can change this behavior by testing for -1 rather than > 0.
Alternatively, you can choose to use other Array methods that are less obscure.
const data = ["", "123456789&"];
const str = "123456789&";
const tests = ["4", "", "123456789&", ";", ["456", "123456789&"]];
function str_find(toFind, toSearch) {
let found = false;
if (!Array.isArray(toFind)) {
if (toSearch.indexOf(toFind) !== -1) {
found = true;
}
} else {
for (var i = 0; i < toFind.length; i++) {
found = str_find(toFind[i],toSearch);
}
}
return found;
}
tests.forEach(t=>console.log("test: ", t, str_find(t, data)));

Related

Palindrome Index HackerRank JS

I am currently trying to solve the HackerRank Palindrome Index challenge. https://www.hackerrank.com/challenges/palindrome-index/problem
My function seems to be returning "undefined" instead of the solution (the index that should be changed for the string to become a palindrome. Why?
function palindromeIndex(s) {
// Write your code here
const reverse = (string) => s.split("").reverse().join("");
var reversed = reverse(s);
if (reversed === s) {
return -1;
} else {
for (let i = 0; i < s.length; i++) {
// splice the array to remove index i and then compare
let myArray = s.split("");
if ((myArray.splice(i, 1).join("")) === reverse(myArray.splice(i, 1).join(""))) {
return i;
}
} ;
}
}
console.log(palindromeIndex("racezcar"));
Your reverse function is always operating on the same input parameter s to the function, because the local parameter of the reverse function would be called string. Thus, whenever you are calling reverse(something) you are getting back the original input reversed.
You seem to have a misunderstanding on how Array.splice works.
it works in place ie modifies the array you call it on
it returns the removed elements and not the modified array
In your case, it seems easier to use substr instead of splice ...
function palindromeIndex(s) {
// Write your code here
const reverse = (string) => string.split("").reverse().join("");
if (s === reverse(s)) {
return -1;
} else {
for (let i = 0; i < s.length; i++) {
let spliced = s.substr(0, i) + s.substr(i+1);
if (spliced === reverse(spliced))
return i;
}
}
//return whatever specified, when the input can't be
//converted into a palindrome ...
}
console.log(palindromeIndex("racezcar"));
console.log(palindromeIndex("racezcars"));
This code still returns undefined when there is no way to turn the input into a palindrome,
The reason your function is returning undefined is due to your reverse function. There is a minor mistake where you call s instead of string:
const reverse = (string) => s.split("").reverse().join("");
should be changed to:
const reverse = (string) => string.split("").reverse().join("");
Otherwise, you still have a bit of work to do to get it working as expected.

Function Iterations Inquiry

I have been given the task of creating a function that iterates through an array. Below is what I have, but Iā€™m getting undefined. What am I missing?
function lookingForDave(arr) {
for (var i = 0; i < arr; i++) {
if (array.forEach === 'Dave') {
return 'I found him';
} else {
return 'Not Dave';
}
}
}
var testArray = ['Dave'];
console.log(lookingForDave(testArray));
You need to check an element of the array against a value, then return if found, otherwise return 'Not Dave' at the end of the function.
If you return at the first check of the value and return not found, you omit all other elements for checking.
function lookingForDave(array) {
for (var i = 0; i < array.length; i++) {
if (array[i] === 'Dave') {
return 'I found him';
}
}
return 'Not Dave';
}
var testArray = ['Dave'];
console.log(lookingForDave(testArray));
Another solution could be to use Array#includes and return the wanted string.
function lookingForDave(array) {
return array.includes('Dave')
? 'I found him'
: 'Not Dave';
}
var testArray = ['Dave'];
console.log(lookingForDave(testArray));
You could use find rather than a for loop. It looks as if you want to return after you first find a match. Array.find will return the value of the first matching criteria.
In the below case if the element in the array is equal to Dave. If there is no match then we will iterate through each item in the array and return undefined.
We can then use the conditional (ternary) operator to test if an item was found.
function lookingForDave (arr){
const found = arr.find(el => el === 'Dave');
return found ? 'found him' : 'Not Dave';
}
let testArray = ['Dave'];
lookingForDave(testArray);
conditional (ternary) operator
Array find
Here's yet another solution:
function lookingForDave(array) {
return array.some(el => el === "Dave") ?
"It's Dave" :
"Not Dave!";
}
var testArray = ["Dave", "Bob", "Sam"];
console.log(lookingForDave(testArray));
Here's hoe it works:
some() takes a function that is run for each and every element in your array. The function that you pass as an argument must return a truthy or falsy value.
If any of those return statements is truthy, some() returns true.
Using a the ternary operator we check if it's true we return "It's Dave" and otherwise "Not Dave!".
Hope that helps!

Behaviour of return variable in a Javascript function

This works, but I don't understand why:
function hasUppercase(input) {
for (var i = 0; i < input.length; i++) {
if (input[i] === input[i].toUpperCase()) {
return true
} else {
return false
}
}
}
console.log(hasUppercase("no"));
console.log(hasUppercase("Yes"));
How come the 'true' for the 'Yes' beats all the falses?
For all characters, you could just return (early exit) if you have found one uppercase letter - in cases of lower case, you need to iterate to the end of the string.
function hasUppercase(input) {
for (var i = 0; i < input.length; i++) {
if (input[i] === input[i].toUpperCase()) {
return true;
}
}
return false;
}
console.log(hasUppercase("no"));
console.log(hasUppercase("Yes"));
console.log(hasUppercase("yeS"));
Your problems are due to the return false statement, which makes function return on first non-uppercase character. The way it is constructed, it will always return after first character. Others already gave you solutions, I'll give you more concise way to achieve the same:
ES2015 (ES6)
const hasUpperCase = in => in.split('').some(c => c === c.toUpperCase());
// Demo:
console.log(hasUpperCase('no'));
console.log(hasUpperCase('yeS'));
Previous versions
function hasUpperCase(input) {
return input.split('').some(function isCharUpperCase(char) {
return char === char.toUpperCase();
});
}
// Demo:
console.log(hasUpperCase('no'));
console.log(hasUpperCase('yeS'));
This function checks only the first character of a given input. If the first character is in Uppercase then it returns true else it returns false. The function quits after first iteration.
So if the given input is like 'yEs' then it returns false. As it checks only the first character 'y' and exits.

Function that checks whether all characters in a string are equal javascript - Homework Warning

I found a solution to this homework question, but I dont feel its the most efficient way to tackle the problem. Interested in other solutions I should explore.
Question:
Write a function named allEqual that returns true if every character in the string is the same
Example:
If you pass "aaa" it should return true
If you pass "aba" it should return false
*/
My Code
var stringAE = "aba";
function allEqual(string) {
var stringAENew = "";
for (var i = 0; i < string.length; i++) {
if (string[0] === string[i]) {
stringAENew += string[i];
console.log(stringAENew)
}
}
return stringAENew === string;
}
allEqual(stringAE)
Simple solution using .every().
function allEqual(input) {
return input.split('').every(char => char === input[0]);
}
console.log(allEqual('aba')); // false
console.log(allEqual('aaa')); // true
console.log(allEqual('')); // true
You can return false immediately once you find a character that doesn't match the first character. If you make it through the whole loop, return true because all the characters must have matched.
function allEqual(string) {
for (var i = 1; i < string.length; i++) {
if (string[i] != string[0]) {
return false;
}
}
return true;
}
You can also start your loop at i = 1, since the first character is obviously equal to itself, so there's no need to test it.
Can be done with regex too
function allEqual(str) {
return /^(.)\1*$/.test(str);
}
Although probably not so effective.
This ES6 solution also works for strings with Unicode code points in other than the first plane, i.e. with codes outside of the 16 bit range:
function allEqual(string) {
return [...string].every( (x, _, a) => x === a[0]);
}
console.log(allEqual('aaaa')); // true
console.log(allEqual('aaaba')); // false
// Next one fails in solutions that don't support multi-plane unicode:
console.log(allEqual('šŒ†šŒ†šŒ†')); // true
console.log(allEqual('')); // true
There's no reason to construct a result string. Just go over all the characters and compare them to the first one (as you've been doing). If you found a different character, the result is false. If you've gone over all the characters and haven't found a different one, the answer is true (note that this includes the edge cases of an empty string and a single character string):
function allEqual(string) {
for (var i = 1; i < string.length; i++) {
if (string[0] !== string[i]) {
return false;
}
}
return true;
}
I'm a little late for the party, but as I needed to do this on a project, I came up with another approach:
function allEqual(input) {
return input === '' || new Set(input).size === 1;
}
console.log(['', 'aaa', '11', '####', 'aba', '12', '###%', null, undefined].map(item => ({
item,
allEqual: allEqual(item),
})));

Cheking if element is in array js

I am new to JavaScript and i will appreciate some help . I try to search array for element but i cant find the right solution . First i tried this , but no success.
var find = function(string, array) {
for(i=0;i>=array.length-1;i++){
if(array[i]==string){
return true;
}
else{
return false;
}
}
};
Then i tried this
var find = function(string, array) {
if(array.indexOf(string)>-1){
return true;}
else{
return false;
}
};
but it doesn't work with numbers
This are my tests
Test.assertEquals(find("hello", ["bye bye","hello"]), true);
Test.assertEquals(find("2", ["bye bye","2"]), true);
Test.assertEquals(find("2", ["bye bye",2]), false);
You are returning false the first time an element is found that doesn't match what you are looking for. You should only return false once the entire array has been processed. Your loop is also incorrect, if i is 0, it will never be greater than or equal to the array length unless the array is empty:
var find = function(string, array) {
for(i=0; i < array.length; i++) {
if(array[i]==string) {
return true;
}
}
return false;
};
You should also focus on naming conventions. Your function is called find, but it doesn't actually return the found element. I would name the function contains.
This is a good learning exercise, but don't reinvent the wheel:
[1,2,3,4,5,6].indexOf(foo) > -1
This will return true if foo is in the array.
Assuming you have a Test.assetEquals Function just use the build in array function:
Test.assertEquals((["bye bye","hello"].indexOf('hello') > -1),true);
With type conversion:
var a = [1, 2, 3];
if (a.some(function (x) { return x == "2" })) {
...
}
Strict comparison:
if (a.indexOf("2") >= 0) {
...
}

Categories

Resources