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;
}
}
Related
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
}
I have these array and variable:
var arr = [['one','blue'], ['two','red'], ['three','green']]
var variable = 'thre';
Also I have this code:
arr.map(function(x){
if(x[0].indexOf(variable) >= 0)
{
alert('Number is found');
}
});
As you know, map works as a loop, and in the array above, there is three items and then map executes its statement 3 times. So that alert will be run.
Now I'm trying to limit the mapping, I mean I want to execute a statement 2 times. So I user for() like this:
for ( var c = 0; c < 2; c++ ) {
if ( arr[c][0].indexOf(variable) >= 0 )
{
alert('number is found');
}
}
But ^ doesn't work, It gives me this error:
Uncaught TypeError: Cannot read property '0' of undefined {in line 2}
How can I fix it?
EDIT: Here is my code in reality:
ZippedArray.map(function(x){
if(x[0].indexOf(name) >= 0)
{
MatchesNames.push(x[0]);
MatchesIds.push(x[1]);
}
});
I want this output:
MatchesNames = MatchesNames.slice(0,2);
MatchesIds = MatchesIds.slice(0,2);
How to limit .map() ? I want something like break; after 2 times.
Based on your comments, it seems you want to loop until you've found two matches in the if condition.
In that case, you can use .some(), which will halt the loop as soon as you return true (or any truthy value).
ZippedArray.some(function(x){
if(x[0].indexOf(name) >= 0)
{
MatchesNames.push(x[0]);
MatchesIds.push(x[1]);
}
return MatchesNames.length == 2; // Breaks when this returns `true`
});
This example assumes that MatchesNames was empty before you called .some().
If there could be other items in the array, and you just want to push two more in at the most, then you could keep a count.
var found = 0;
ZippedArray.some(function(x){
if(x[0].indexOf(name) >= 0)
{
MatchesNames.push(x[0]);
MatchesIds.push(x[1]);
found++;
}
return found == 2;
});
If you want to use a traditional for loop, then do this:
var found = 0;
for (var i = 0; i < ZippedArray.length; i++) {
var x = ZippedArray[i];
if(x[0].indexOf(name) >= 0)
{
MatchesNames.push(x[0]);
MatchesIds.push(x[1]);
found++;
}
if (found == 2) {
break;
}
}
The code you posted does not throw an error.
But when you're limiting the loop count of iterating an array, you should add a range check for the index:
for (var c = 0; c < 2 && c < arr.length; c++) {
// or alternatively
for (var c = 0, l = Math.min(2, arr.length); c < l; c++) {
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;
}
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"]);
I am developing a program in which I need to stop a loop when a flag is true. This is a short example of that I want:
var aux = true;
for(i=0; i < limit && aux; i++)
{
...
if (condition)
aux = false;
}
When the condition should end the loop. But this is not true. What is the problem?
EDIT:
The code is as follows:
aux = true;
for(j=posX+1; j <= limitXTop && aux; j++)
if(j != limiteXSuperior)
{
if(map.getXY(j,posY)[0] == 2)
{
aux = false;
}
else
// Change
...
}
...
I print a message to check if the execution enter in the IF and it enter.
Instead of using the condition on the for, use only a break statement.
for(i=0; i < limit; i++)
{
...
if (condition)
break;
}
Let me guess ... i was not defined ?