How can I loop through two arrays comparing values in Javascript? - javascript

I have the following Javascript function where the parameters newValue and oldValue are arrays of integers and the same length. Any values in these arrays can be an integer, undefined or null:
function (newValue, oldValue) {
});
Is there some way that I could check the values in the arrays one element at a time and then do an action only if:
newValue[index] is >= 0 and < 999
oldValue[index] is >= 0 and < 999
newValue[index] is not equal to oldValue[index]
What I am not sure of is how can I handle in my checks and ignore the cases where newValue or oldValue are not null and not undefined? I know I can do a check as in if (newValue) but then this will show false when it's a 0.
Update:
I had a few quick answers so far but none are checking the right things which I listed above.

compare against null and undefined:
if (newValue[index] !== null && typeof newValue[index] !== 'undefined') {}
for OPs update:
n = newValue[index];
o = oldValue[index];
if (
n !== null && typeof n !== 'undefined' && n >= 0 && n < 999 &&
o !== null && typeof o !== 'undefined' && o >= 0 && o < 999
) {
// your code
}
for array-elements its not necessary to use typeof so n !== undefined is ok because the variable will exist.
n = newValue[index];
o = oldValue[index];
if (
n !== null && n !== undefined && n >= 0 && n < 999 &&
o !== null && o !== undefined && o >= 0 && o < 999 &&
n !== o
) {
// your code
}

This will do it:
function isEqual (newValue, oldValue) {
for (var i=0, l=newValue.length; i<l; i++) {
if (newValue[i] == null || newValue[i] < 0 || newValue[i] >= 999
|| oldValue[i] == null || oldValue[i] < 0 || oldValue[i] >= 999)
continue;
if (newVale[i] !== oldValue[i])
return false;
}
return true;
}

if (newValue != null || newValue != undefined) && (oldValue != null || oldValue != undefined)

Related

Equality operator with multiple values in JavaScript

Is there a simple way to compare multiple values to a single value in Javascript ?
Like, instead of writing :
if (k != 2 && k != 3 && k!= 7 && k!12)
Writing something like :
if (k != {2,3,7,12})
You can use includes instead of multiple equality comparisons.
if (![2,3,7,12].includes(k))
That's boolean algebra:
if (k != 2 && k != 3 && k!= 7 && k != 12)
is equivalent to
if (!(k == 2 || k == 3 || k == 7 || k == 12))
and that's equivalent to
if (![2,3,7,12].includes(k))

Error while accessing javascript array element inspite of having checks

I am doing following in my javascript code
if(
typeof player['stats'] != undefined &&
typeof player['stats']['guild'] != undefined &&
typeof player['stats']['guild']['master'] != undefined &&
typeof player['stats']['guild']['master']['since'] != undefined
)
However I get error:
Cannot read property 'since' of null
I have been stuck with this for a while. Can any javascript gurus help me please?
typeof returns string, so compare against "undefined"
if(
typeof player['stats'] != "undefined" &&
typeof player['stats']['guild'] != "undefined" &&
typeof player['stats']['guild']['master'] != "undefined" &&
player['stats']['guild']['master'] != null &&
typeof player['stats']['guild']['master']['since'] != "undefined"
)
Just check if the value is truthy:
if(
player['stats'] &&
player['stats']['guild'] &&
player['stats']['guild']['master'] &&
player['stats']['guild']['master']['since'] != undefined // only check the last one as it is probably not an object but another value such as 0 (depending on what your data looks like, if you have it as an object then just remove the != undefined check)
)
You could write a fairly simple object getter function which you pass the object and then a dot-delimited key to find a value like so:
function getObj(obj, key) {
return key.split(".").reduce((acc, cur) => {
if (acc !== undefined) {
return acc[cur];
}
return acc;
}, obj);
}
Then, you can grab the value that you want and see if it's undefined or not:
const player = {
stats: {
guild: {
master: {
since: '2004'
}
}
}
};
const since = getObj(player, 'stats.guild.master.since');
if (since) {
// do some code
}
This is a handy utility function you can use on any object and makes your if statement much prettier.
You can also avoid the multiple lookups with a temporary variable:
player = { stats: { guild: { master: null } } }
if ((temp = player.stats) &&
(temp = temp.guild) &&
(temp = temp.master) &&
(temp = temp.since) !== undefined)
console.log(true , temp)
else
console.log(false, temp)
player.stats.guild.master = { since: 'today' }
if ((temp = player.stats) &&
(temp = temp.guild) &&
(temp = temp.master) &&
(temp = temp.since) !== undefined)
console.log(true , temp)
else
console.log(false, temp)

javascript : create for loops into for loops

I had to solve the following problem:-
9 values, from 1 to 9 (0 and 10 not accepted) and all numbers need to be different.
To solve the problem, I made those horrible for loops inside for loops.
(I added 2 more conditions to check if I had one of the solutions)
It is working, but I was wondering how to create those for loops inside for loops in a better way?
Also, each number can't be equal to another. How can you accomplish this another way than I did? (Again, 2 first conditions can be deleted)
Here is code:
var a = 1,
b = 1,
c = 1,
d = 1,
e = 1,
f = 1,
g = 1,
h = 1,
i = 1
var x = 0
var result = []
function calc() {
x = a + (13 * b) / c + d + 12 * e - f - 11 + (g * h) / i - 10
if (x == 66) {
result.push([a, b, c, d, e, f, g, h, i])
}
}
for (a = 1; a < 10; a++) {
calc()
for (b = 1; b < 10; b++) {
calc()
for (c = 1; c < 10; c++) {
calc()
for (d = 1; d < 10; d++) {
calc()
for (e = 1; e < 10; e++) {
calc()
for (f = 1; f < 10; f++) {
calc()
for (g = 1; g < 10; g++) {
calc()
for (h = 1; h < 10; h++) {
calc()
for (i = 1; i < 10; i++) {
calc()
}
}
}
}
}
}
}
}
}
console.log(result)
var result2 = result.filter(function (el) {
return (
el[0] == 5 &&
el[1] == 9 &&
el[0] != el[1] &&
el[0] != el[2] &&
el[0] != el[3] &&
el[0] != el[4] &&
el[0] != el[5] &&
el[0] != el[6] &&
el[0] != el[7] &&
el[0] != el[8] &&
el[1] != el[0] &&
el[1] != el[2] &&
el[1] != el[3] &&
el[1] != el[4] &&
el[1] != el[5] &&
el[1] != el[6] &&
el[1] != el[7] &&
el[1] != el[8] &&
el[2] != el[0] &&
el[2] != el[1] &&
el[2] != el[3] &&
el[2] != el[4] &&
el[2] != el[5] &&
el[2] != el[6] &&
el[2] != el[7] &&
el[2] != el[8] &&
el[3] != el[0] &&
el[3] != el[1] &&
el[3] != el[2] &&
el[3] != el[4] &&
el[3] != el[5] &&
el[3] != el[6] &&
el[3] != el[7] &&
el[3] != el[8] &&
el[4] != el[0] &&
el[4] != el[1] &&
el[4] != el[2] &&
el[4] != el[3] &&
el[4] != el[5] &&
el[4] != el[6] &&
el[4] != el[7] &&
el[4] != el[8] &&
el[5] != el[0] &&
el[5] != el[1] &&
el[5] != el[2] &&
el[5] != el[3] &&
el[5] != el[4] &&
el[5] != el[6] &&
el[5] != el[7] &&
el[5] != el[8] &&
el[6] != el[1] &&
el[6] != el[2] &&
el[6] != el[3] &&
el[6] != el[4] &&
el[6] != el[5] &&
el[6] != el[7] &&
el[6] != el[8] &&
el[7] != el[0] &&
el[7] != el[1] &&
[7] != el[2] &&
el[7] != el[3] &&
el[7] != el[4] &&
el[7] != el[5] &&
el[7] != el[6] &&
el[7] != el[8] &&
el[8] != el[0] &&
el[8] != el[1] &&
el[8] != el[2] &&
el[8] != el[3] &&
el[8] != el[4] &&
el[8] != el[5] &&
el[8] != el[6] &&
el[8] != el[7]
)
})
console.log(result2)
for starters you can make N x nested for loops like this
nested_for in C++
You can handle your problem as a 9 digit number generation
As your digits are not repeating you can discard many iterations. If encoded in the above manner (like nested for) you will came up with something like this:
Generalized Permutation (without repetitions) in C++:
//---------------------------------------------------------------------------
//--- permutation class ver 0.00 --------------------------------------------
//---------------------------------------------------------------------------
#ifndef _permutation_h
#define _permutation_h
/*---------------------------------------------------------------------------
// usage:
permutation per;
per.alloc(N);
per.first();
for (;;)
{
... here per.i[0..N-1] contains actual permutation
... N! permutations
if (!per.next()) break;
}
//-------------------------------------------------------------------------*/
class permutation
{
public:
int *i; // i[N] permutation
BYTE *a; // a[N] item not used yet ?
int N; // items
int ix; // actual permutation layer
permutation() { N=0; i=NULL; a=NULL; ix=0; }
permutation(permutation& b) { *this=b; }
~permutation() { free(); }
permutation* operator = (const permutation *b) { *this=*b; return this; }
permutation* operator = (const permutation &b) { alloc(b.N); for (int j=0;j<N;j++) { i[j]=b.i[j]; a[j]=b.a[j]; } ix=b.ix; return this; }
void alloc(int _N)
{
free();
i=new int[_N];
if (i==NULL) return;
a=new BYTE[_N];
if (a==NULL) { free(); return; }
N=_N;
}
void free ()
{
N=0; ix=0;
if (i!=NULL) delete i; i=NULL;
if (a!=NULL) delete a; a=NULL;
}
void first() // init permutation
{
for (ix=0;ix<N;ix++)
{
i[ix]=ix;
a[ix]=0;
} ix--;
}
bool next() // next permutation return if it is not last
{
int *ii=&i[ix];
for (;;)
{
if (*ii>=0) a[*ii]=1;
for ((*ii)++;*ii<N;(*ii)++) if (a[*ii]) { a[*ii]=0; break; }
if (*ii>=N)
{
if (ix== 0) return false;
*ii=-1; ix--; ii=&i[ix];
}
else{
if (ix==N-1) return true;
ix++; ii=&i[ix];
}
}
}
};
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
The important stuff is in first() and next() members, each permutation is stored in the i[] array as index so set N=9 and your output numbers will be (per.i[0]+1),(per.i[1]+1),...,(per.i[9]+1)
it works in following manner:
first() initialize permutation to state i[9]=(0,1,2,...8) and a[9]=(0,0,0,...0)
I will write this for simplicity like this: i=012345678,a=000000000 where
ix points to last digit
i is the actual permutation
a flags if digit is unused(1) or used(0) (to avoid O(N^N) operation)
next() increment to next valid permutation
Increase the last digit to next unused value. If no unused value set it as unused and increment previous digit. The same goes for overflow. The first iteration will be like this:
i=012345678,a=000000000 // starting iteration
i=01234567? a=000000001 // unset (no unused values)
i=01234568? a=000000010 // increment 8th digit
i=012345687 a=000000000 // set the last digit result
next iteration:
i=012345687 a=000000000 // starting iteration
i=01234568? a=000000010 // unset (no unused values)
i=0123456?? a=000000011 // unset (8->9 overflow)
i=0123457?? a=000000101 // increment 7th digit
i=01234576? a=000000001 // after overflow digit set to lowest free value
i=012345768 a=000000000 // after overflow digit set to lowest free value
I hope it is clear enough.
Of coarse if you use recursion instead of iteration the code will look much nicer but in most languages will run also slower due to stack/heap trashing
As #NikolaDimitroff pointed out this is in C++ instead of javascript so:
ignore new,delete and class members other then first(),next()
set N=9; and arrays i,a can be static like: int i[9]; BYTE a[9];
Here the solution O(N!) for the task in C++:
int a,b,c,d,e,f,g,h,i;
permutation per;
per.alloc(9);
per.first();
for (;;)
{
if ((per.i[0]+1)
+(13*(per.i[1]+1)/(per.i[2]+1))+(per.i[3]+1)
+(12*(per.i[4]+1))
-(per.i[5]+1)-11
+((per.i[6]+1)*(per.i[7]+1)/(per.i[8]+1))-10
==66)
{
a=per.i[0]+'1';
b=per.i[1]+'1';
c=per.i[2]+'1';
d=per.i[3]+'1';
e=per.i[4]+'1';
f=per.i[5]+'1';
g=per.i[6]+'1';
h=per.i[7]+'1';
i=per.i[8]+'1';
// here a,b,c,d,e,f,g,h,i holds the solution
break;
}
if (!per.next()) break;
}

JavaScript short circuit evaluation error?

The two below snippets of JS code have had me confused, in my eyes both should work the same, due to short circuit evaluation. But for some reason snippet '1' causes the error (on the third line):
Cannot read property 'match' of undefined
Array 'a' holds 3 character values user entered into inputs. I want the code to return true if the char is undefined, an empty string, or a letter or number.
To be clear, this fails when a = ['a', '/'];
Snippet 1)
return typeof a[0] === 'undefined' || a[0] === '' || a[0].match(/^[a-z0-9]+$/i)
&& typeof a[1] === 'undefined' || a[1] === '' || a[1].match(/^[a-z0-9]+$/i)
&& typeof a[2] === 'undefined' || a[2] === '' || a[2].match(/^[a-z0-9]+$/i);
Snippet 2)
if (typeof a[0] === 'undefined' || a[0] === '' || a[0].match(/^[a-z0-9]+$/i)) {
if (typeof a[1] === 'undefined' || a[1] === '' || a[1].match(/^[a-z0-9]+$/i)) {
if (typeof a[2] === 'undefined' || a[2] === '' || a[2].match(/^[a-z0-9]+$/i)) {
return true;
}
return false;
}
return false;
}
return false;
Surely a[2].match should never be evaluated if a[2] is undefined due to the first conditional in the 'if'?
The answer is simple. Take a look to the order of operations .
AND binds more than OR.
In your Snippet 1 the expression is like:
a1 || b1 || (c1 && a2) || b2 || (c2 && a3) || b3 || c3
Your Snippet 2 is like:
(a1 || b1 || c1) && (a2 || b2 || c2) && (a3 || b3 || c3)
#Christoph is right but you also need to add something like !== null after match like
return (typeof a[0] === 'undefined' || a[0] === '' || a[0].match(/^[a-z0-9]+$/i) !==null ) && (typeof a[1] === 'undefined' || a[1] === '' || a[1].match(/^[a-z0-9]+$/i) !== null ) && (typeof a[2] === 'undefined' || a[2] === '' || a[2].match(/^[a-z0-9]+$/i) !== null);
You can take a look at this fiddle http://jsfiddle.net/dv360q1p/1/ which implements your question

Location.pathname.indexOf not working with 'Or' ( || )

I'm trying to use location.pathname.indexOf to make conditional jQuery work on some pages on my site.
This works:
if (location.pathname.indexOf("/example/5820.htm") != 0){}
This works:
if (location.pathname.indexOf("/example-1/3569.htm") != 0) {}
This doesn't work:
if (location.pathname.indexOf("/example/5820.htm") != 0 || location.pathname.indexOf("/example-1/3569.htm") != 0) {}
I've done this a ton of times and for some reason this code is not working. I'm wondering if I'm missing something little in the code or if it's something else?
Tim already answered this question, but don't forget:
.indexOf() will return -1 when the string isn't found, not 0.
if (location.pathname.indexOf("/example/5820.htm") != 0){}
Should be:
if (location.pathname.indexOf("/example/5820.htm") != -1){}
Or:
if (location.pathname.indexOf("/example/5820.htm") >= 0){}
http://www.w3schools.com/jsref/jsref_indexof.asp
basically you're saying this:
var a = 0;
var b = 1;
if (a != 0 || b != 0) {};
Which is equal to
if (!(a == 0 && b == 0)) {};
However, you actually want this:
if (!(a == 0 || b == 0)) {};
Which is equal to:
if (a != 0 && b != 0) {};

Categories