Merging two comparisons with a common variable together - javascript

I have a function as follows:
bullets.forEach(function (b) {
ships.forEach (function (s) {
if (b.x1 >= s.x1 && b.x1 <= s.x2 && b.y1 >= s.y1 && b.y2 <= s.y2) {
animationBucket = animationBucket.filter((i) => {
return (i != b && i != s);
}
);
I want to merge those comparisons which use the same variables like i != b && i != s. I want it to be like i is not equal to b and s using i a single time. Is it possible? If yes, then how?
Edit: I will not be using the same inequality operator all the time. I want a code that should work for all comparisons like, i < j && i > k, i == b && i != s and so on. To be simple, I just want to make the variable (here i ) used two times (or more) to be used only once or maybe in shorter way.

Not exactly, but you can do something like:
return ![b, s].includes(i);

There are not such things in JavaScript yet. But, maybe this may be added in future :) Till that you can use some helper functions to do your tasks.

Related

I am trying to get 3 conditions in one if . But it's not working

I need to match three conditions so that the page can show the appropriate result for that filters. I tried adding the && between three of the conditions but it doesn't work.
I am not revealing the real code here, but I've shown it without the original var names.
if(localStorage.getItem("eg1") == 30000 && eg2 == 1 && eg3 == use){};
eg2 and eg3 are just variables, they are not localstorage.
It should be:
if((localStorage.getItem("eg1") == 30000) && (eg2 == 1) &&
(eg3== use)){};
Here is a bit cleaner way to do it:
const a = ["eg1", "eg2", "eg3"].map(e => localStorage.getItem(e));
if (a[0] == 30000 && a[1] == 1 && a[2] == use) {
//
}
And a less dynamic but shorter way to do it:
if ([30000, 1, use].map((e, i) => e == localStorage.getItem("eg" + i++)).includes(false)) {
}
Try to decompose the problem in order to analyze it better:
var e1 = localStorage.getItem("eg1") === 30000;
var e2 = eg2 === 1;
var e3 = eg3 === use;
I've used triple equal since i suppose you don't want type coercion.
Since you can't show the original code, if you don't put some log of your results it's quite difficult to imagine what variables can contain with appropriate level of certainty.
Sure is that looking to your conditions independently should help you to identify where your guesses fall to fix what appears as a simple branch condition.
localStorage.getItem returns the value as string.
Try using if(localStorage.getItem("eg1") == "30000" && eg2 == 1 && eg3 == use){};

Appropriate way to check if 4 strings are duplicated in JS [duplicate]

Working in Javascript, I am trying to see if 5 different variables all contain the same value at a given time. The value could be 1 of 6 things, but I need to see if they are all the same regardless of which value it is. I have tried this:
if (die1 == die2 & die1 == die3 & die1 == die4 & die1 == die5) {
yahtzeeQualify == true;
}
and this:
if (die1 == die2 == die3 == die4 == die5) {
yahtzeeQualify == true;
}
Are either of these valid? If so, there is probably an error in my code somewhere else...if not, I'd really appreciate some help. I also have these variables in an array called dieArray as follows:
var dieArray = [die1, die2, die3, die4, die5];
It would be cool to learn a way to do this via the array, but if that isn't logical then so be it. I'll keep trying to think of a way on my own, but up until now I've been stuck...
Are either of these valid?
They are "valid" (as in this is executable code) but they don't perform the computation you want. You want to use a logical AND (&&) not a bitwise AND.
The second one is just wrong. You run into type coercion issues and end up comparing die1 to either true or false.
It would be cool to learn a way to do this via the array
You can use Array#every and compare whether each element is equal to the first one:
if (dieArray.every(function(v) { return v === dieArray[0]; }))
// arrow functions make this nicer:
// if (dieArray.every(v => v === dieArray[0]))
Solution with the Array.reduce:
var values = [die1, die2, die3, die4, die5];
var yahtzeeQualify = values.reduce(function(memo, element) {
return element === values[0];
});
The 1st one is what you want, but it's messed up. You want && not &
The 2nd one is logically wrong.
To do it with an array
yahtzeeQualify = dieArray.every(function(n){ return n === dieArray[0] })

Can you compare multiple variables to see if they all equal the same value in JS?

Working in Javascript, I am trying to see if 5 different variables all contain the same value at a given time. The value could be 1 of 6 things, but I need to see if they are all the same regardless of which value it is. I have tried this:
if (die1 == die2 & die1 == die3 & die1 == die4 & die1 == die5) {
yahtzeeQualify == true;
}
and this:
if (die1 == die2 == die3 == die4 == die5) {
yahtzeeQualify == true;
}
Are either of these valid? If so, there is probably an error in my code somewhere else...if not, I'd really appreciate some help. I also have these variables in an array called dieArray as follows:
var dieArray = [die1, die2, die3, die4, die5];
It would be cool to learn a way to do this via the array, but if that isn't logical then so be it. I'll keep trying to think of a way on my own, but up until now I've been stuck...
Are either of these valid?
They are "valid" (as in this is executable code) but they don't perform the computation you want. You want to use a logical AND (&&) not a bitwise AND.
The second one is just wrong. You run into type coercion issues and end up comparing die1 to either true or false.
It would be cool to learn a way to do this via the array
You can use Array#every and compare whether each element is equal to the first one:
if (dieArray.every(function(v) { return v === dieArray[0]; }))
// arrow functions make this nicer:
// if (dieArray.every(v => v === dieArray[0]))
Solution with the Array.reduce:
var values = [die1, die2, die3, die4, die5];
var yahtzeeQualify = values.reduce(function(memo, element) {
return element === values[0];
});
The 1st one is what you want, but it's messed up. You want && not &
The 2nd one is logically wrong.
To do it with an array
yahtzeeQualify = dieArray.every(function(n){ return n === dieArray[0] })

Javascript dynamic conditioning

I want to build a IF condition which is built dynamically based on the parameters it gets. More over, this is expected to be built as a plugin.
For instance, there are 3 parameters for student object, called age,name, phone_numbers. Also, there is a option object for selection parameters.
In the condition,
if(student.age >option.age & student.name == option.name & student.phonenumbers == option.phonenumbers ){
// do stuff
}
If any parameter is missing, it should not be included in the condition. For example, assume, in case option.name is undefined, then the if condition should be prepared as following,
if(student.age >option.age & student.phonenumbers == option.phonenumbers ){
// do stuff
}
Moreover, why this kind of thing is required is, here an array of (500 objects) students objects are iterated. The above condition can be splitted into seperat conditions, but then the iteration will be multipled by the number of conditions !!!. So I m looking for a way to add all conditions into one.
However, my approach is, create the expression as a string and then execute it with eval(..),but as far as I know that using eval can lead vulnerabilities.
Any one let me know a way to implement a dynamic conditions.
Note that the JavaScript and operator is &&.
For your example, this should work:
if((!student.age || student.age>option.age) &&
(!student.name || student.name==option.name) &&
(!student.phonenumbers || student.phonenumbers==option.phonenumbers)
) {
}
How about
function testStudent(student,option) {
var res = [];
var test = true;
if (student.age) res.push(student.age > option.age);
if (student.name) res.push(student.name == option.name);
if (student.phonenumbers) res.push(student.phonenumbers == option.phonenumbers);
for (var i=0;i<res.length;i++) {
test = test && res[i];
}
if (res.length > 0 && test) {
//do stuff
}
}
generic:
function testObjects(obj1,obj2) {
for (var o in obj1) { // assuming obj2 is a superset of obj1
if (o === "age" && obj1.age <= obj2.age) return false;
if (obj1.hasOwnProperty(o) && obj1[o] != obj2[o]) return false;
}
return true;
}
var ok = testObjects(student,option);
You can have your conditions in functions and those functions in an Array. so then you can do a loop in the Array and call every function (condition).
var aConds = [];
function firstCond(params) {return (params<0)};
function secondCond(params) {return(params!='hi')};
aConds.push(firstCond);
...
for(var i=0;i<aConds.length;i++)
{
if(!aConds[i](params)) console.log("a condition has not been meet");
}
Would it work to allow undefined in each condition?
if((student.age == undefined || student.age > option.age) && (student.name == undefined || student.name == option.name) ...

Prevent javascript from going out of an array

Is there any way I can prevent javascript from dropping an error if I try to go into a non existing array index?
Example: array[-1] would return error and eventually break all my code. How can I let it just return 'undefined' and let my script go on? I can implement an if statement before checking the array (so that if the index is minor than zero or major than the array size it would skip it) but this would be very tedious!
this is my code:
if (grid[j-1][i])
n++;
if (grid[j+1][i])
n++;
if (grid[j][i+1])
n++;
if (grid[j][i-1])
n++;
if (grid[j-1][i-1])
n++;
if (grid[j+1][i+1])
n++;
if (grid[j-1][i+1])
n++;
if (grid[j+1][i-1])
n++;
It is inside of two loops which both sees J and I starting from zero. I don't want to change them and neither writing another if statement (as you can see, there are already too much of them!). Is there any solution?
Thanks!
If you know the measures of your grid, you can put "sentinel cells" around it.
If you add a -1st index to an array x, it does not count to x.length. Putting an additional last element into the list would increment x.length.
I daresay using sentinel cells combined with the arithmetic counting algorithms mentioned by d_inevitable would be the fastest solution, since it would not involve branches. You even can omit the !! because true will evaluate to 1 and false to 0 in an equalization.
Update:
Do not use index -1. Its an awful lot slower that normal array indexes. See http://jsperf.com/index-1.
You could use ||, which muffles errors, e.g.:
(grid[j-1] || [])[i] || false
(I haven't tested this, but it should work)
Edit: updated based on am not i am's suggestion
A less tedious way while still using ifs would be checking the first index if it's defined:
if (typeof grid[j-1] != "undefined" && grid[j-1][i])
You could create a function to do the checks:
function getArrayValue(arr,key) {
if( key < 0 || key >= arr.length) return null;
return arr[key];
}
But really you should be avoiding out-of-bounds keys anyway.
I would do this:
for(m = Math.max(j-1,0) ; m <= Math.min(j+1,grid.length-1) ; m++)
for (p = Math.max(i-1,0) ; p <= Math.min(i+1, grid[m].length-1) ; p++)
n += !(m == j && p == i) && !!grid[m][p];
How about this for your solution?
for (dj = -1; dj <= 1; ++dj) {
for (di = -1; di <= 1; ++di) {
if ((dj || di) && grid[j+dj] && grid[j+dj][i+di]) {
n++;
}
}
}
If you refactor all those ifs into a single loop like the above, then having to do the extra conditional is not so bad.

Categories

Resources