checking strings in an array - javascript

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"]);

Related

Return "True" if all the characters in a string are "x" or "X" else return false

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
}

check the alphabetical order

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.

javascript determine which OR statement triggered if statement

I have a condition like this (this is much simplified, they are actually events):
if(!a || !b || !c || !d){
//do something with 1,b,c, or d
}
how do I determine which var triggered the if? Doing if(a) else if(b) is not really a good option here as it will result in a lot of repeated code.
You can just try with a function that returns the index of the first true condition, or -1 if all conditions are false:
var conditions = [];
conditions.push(a);
conditions.push(b);
conditions.push(c);
conditions.push(d);
// ...
var triggerer = (function(){
for(var i = 0; i < conditions.length; i++){
if(conditions[i]){ return i; };
}
return -1;
})();
if(triggerer != -1){
// Do something with conditions[triggerer]
}else{
// Do something when everything is false
}
Store your conditions in an array and check them in a loop:
var values = [a, b, c, d];
for(var i = 0; i < values.length; i++) {
if(!values[i]) {
//...
// `values[i]` is the *first* condition that satisfies the `if` statement.
break;
}
}

Why is my while loop not iterating through completely?

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;
}

Why indexOf in javascript not working?

I'm not sure what I'm doing wrong here. The first instance that I use indexOf it works perfectly fine, but when I use it the second time it's not returning the result that I'm expecting.
function mutation(arr) {
//return arr;
res = "";
for (var x=0; x<arr[1].split("").length; x++) {
if (arr[0].indexOf(arr[1].split("")[x]) !== -1) {
res += "t";
} else {
res += "f";
}
}
// res = ttt
if (res.indexOf("f") !== -1) {
return true;
} else {
return false;
}
}
mutation(["hello", "hey"]);
// this returns true instead of false
mutation(["floor", "loo"]);
// returns false instead of true
mutation should return false if an element from arr[1] is not present in arr[0] else return true.
your code isn't working because when you say:
res.indexOf("f") != -1
this means: "I found an f", but you're treating it as if it means "I did not find an f".
In your case that you want to return false if you find an 'f', but you're returning true. Flip your true and false cases:
if (res.indexOf("f") != -1) {
return false;
} else {
return true;
}
ALSO your for loop is wrong because x starts at 0, so you need to go to < length not <= length of your string.
for (var x=0; x < arr[1].split("").length; x++) {
and now your code works as you wanted it to.
Just edited your code. Click on the <p> to check:
function mutation(arr) {
//return arr;
res = "";
for (var x=0; x< arr[1].split("").length; x++) {
res += arr[0].indexOf(arr[1].split("")[x]) > -1 ? 't' : 'f';
}
return res.indexOf('f') > -1;
}
$('p').click(function(){
alert(mutation(["hello", "hey"]));
alert(mutation(["floor", "loo"]));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click me</p>
If you simplify the logic a bit, that's easier to check:
function mutation(arr) {
return arr[1].split('').reduce(function(res, x) {
return arr[0].indexOf(x) >= 0;
}, true);
}
Thanks Leon for the correction.
I tried to not chance your logic, the mistake are:
You're trying to compare with all characters on the array[0], not only the first.
If you find a character equals on the first character on array[0] you should return true.
Correct code:
function mutation(arr) {
res = "";
for (var x=0; x<=arr[1].split("").length; x++) {
if (arr[0].split("")[0].indexOf(arr[1].split("")[x]) !== -1) {
return true;
}
}
return false;
}

Categories

Resources