2D Array in While loop bounds - javascript

I'm having some issues with figuring out how to work with a 2D array and a while loop.
Here's the relevant code snippet:
while (
table[i - count][j] === 0 ||
table[i + count][j] === 0 ||
table[i][j - count] === 0 ||
table[i][j + count] === 0
) { ... count++; }
I get the following error when running my snippet:
TypeError: Cannot read property '0' of undefined
Now I understand that this is happening because if I have i = 0 then table[i - count][j] would been it is checking table[-1][j]. Obviously this shouldn't work but that is the purpose of the while loop that I've implemented.
I want the code to stop running when either the edge of this 2D array is out of bounds (like explained above) or if the element's value is 0.
Currently it gives me the error when I just need it to stop and carry on with the code after the while loop. How do I solve this?
EDIT:
Yeah I'm sure I want these conditions to be &&. The main issue is that i -count could result in a negative number. Or i + count could result in a number out of bounds for the array.
How do I deal with those out of bounds occasions in this while loop?

You need to make shure the array exists before accessing its keys, and checking for 0 or undefined is irrelevant as both are falsy :
while(
(table[i - count] || [])[j] &&
(table[i + count] || [])[j] &&
(table[i] || [])[j + count] &&
(table[i] || [])[j - count]
) count++;

Right I've found a solution. It's probably not optimal in general but for what I'm doing it's perfect:
while (
i - count >= 0 &&
j - count >= 0 &&
i + count < table.length &&
j + count < table[i].length
) {
if (
table[i - count][j] === 0 ||
table[i + count][j] === 0 ||
table[i][j - count] === 0 ||
table[i][j + count] === 0
) return prod;
prod *= (
table[i - count][j] *
table[i + count][j] *
table[i][j - count] *
table[i][j + count]
);
count++;
}

As commented before, using I would suggest using a function that returns a boolean value. This will keep your loop clean and you can choose to have a more descriptive code for conditions.
function validate(array, i, j, count){
// To cover case when either variable is 0
if(i && j){
let prev = array[i - count];
let next = array[i + count];
let curr = array[i];
return (
(j < prev.length && prev[j] === 0) ||
(j < next.length && next[j] === 0) ||
// Since we have already added a check for value !== 0,
// we just have to check for out of bound here.
(j < curr.length -1) && (
curr[j - count] === 0 ||
curr[j + count] === 0
)
)
}
return false;
}
while (validate(table, i, j, count)) { ... count++; }

Assuming your conditions are connected by "and"
Just add extra conditions to check for valid values/bounds for your array index
while (
table[i - count][j] !== 0 && table[i - count][j] !== undefined &&
table[i + count][j] !== 0 && table[i + count][j] !== undefined &&
table[i][j - count] !== 0 && table[i][j - count] !== undefined &&
table[i][j + count] !== 0 && table[i][j + count] !== undefined &&
i - count > 0 &&
j - count > 0
) { ... count++; }

Related

How to short the expression?

I have that expression
if (a === Infinity && b === 0 || a === -Infinity && b === 0 || a === 0 && b === Infinity || a === 0 && b === -Infinity) {
return NaN
}
I want short it, but I have no idea how to do this
UPDATE
If it possible, I cant use isFinite(), how to shorten else?
You can use !isFinite() to test if it's either Infinity or -Infinity.
if ((!isFinite(a) && b === 0) || (!isFinite(b) && a === 0)) {
return NaN;
}
If a and b are number typed, then:
if (!(a*b || isFinite(a+b))) return NaN;
If your linter warns about use of global functions, then:
if (!(a*b || Number.isFinite(a+b))) return NaN;
If you can't use multiplication:
if (!(a && b || Number.isFinite(a+b))) return NaN;
Math.absing both and then checking that the minimum is 0 and the maximum is infinity should do it.
const nums = [a, b].map(Math.abs);
if (Math.min(...nums) === 0 && Math.max(...nums) === Infinity) {
return NaN;
}
Can also sort the array.
const nums = [a, b]
.map(Math.abs)
.sort(a, b) => a - b); // .sort() works too, but could be more confusing
if (nums[0] === 0 && nums[1] === Infinity)) {
return NaN;
}

First Unique Character in a String Leetcode - using pointers (javascript)

Given a string, find the first non-repeating character in it and return its index. If it doesn't exist, return -1.
leetcode question
"cc" // -1
"ccdd" // -1
"leetcode" // 1
"loveleetcode" // 2
"abcabd" // 2
"thedailybyte" // 1
"developer" // 0
My approach passed all the test cases except the 2nd test case "ccdd". I am expecting -1 but receiving 4. Not sure why.
var firstUniqChar = function(s) {
if(!s || s.length === 0 ) return -1
else if(s.length === 1) return 0
let pointer1 = 0
let pointer2 = pointer1 + 1
if(s.length > 2){
while(pointer2 <= s.length - 1){
if(s[pointer1] !== s[pointer2])
pointer2++
else if(s[pointer1] === s[pointer2])
pointer1++
}
return pointer1
}
return -1
};
this is too old, but still can be too much shorter:
const firstUniqChar = (_str) => {
for (let i= 0; i < _str.length; i+= 1) {
if (_str.indexOf(_str[i]) === _str.lastIndexOf(_str[i])) return i+1;
}
return -1;
}

javascript, combining AND, OR in an if starement

I would like my code to be able to do the following:
IF (value1 is less than -1 AND variable2 does not equal either 6 or 5) then...
So far I could get a single if and to work as follows;
if ( (value < -1 && (day !== 6)) ) sendEmail(value)
but as soon as I add in the second or it falls over. What am I doing wrong? I have tried it in a few different ways but below are a couple of examples that did not work.
if ( (value < -1 && (day !== 6 || 5)) ) sendEmail(value)
if ( (value < -1 && (day !== 6 || day !== 5)) ) sendEmail(value)
Think about your logic. Basically what you want is:
IF (value1 is less than -1 AND variable2 is not equal to 6 AND variable2 is not equal to 5)
Therefore your if statement can be written as:
if (value < -1 && day != 6 && day != 5) sendEmail(value);
if(value < -1 && day !== 6 && day !== 5) sendEmail(value)
should do the trick.

handle empty strings at array.sort(?) callback in chrome is very slow

in js i have to sort a lot of array elements(100k-1kk).
İn production its possible to have many blank ('') strings.
in my sort function i handle empty values - so that this values always come last .its ok.. until i have many null or undefined or blank('') values in data
if data have many nulls for example or blank strings performance is veeery slow.
And the main thing is that this fragment very slow at Chrome (at least last version for now 49.0.2623.110 m)
firefox(45.0.1) works very well (even with standart case without empty data my test x10 faster ??)
just test.with chrome and firefox
P.S. i know jsperf is more preferable for that.anyway
https://jsfiddle.net/3h0gtLu2/18/
data = []
var i = 0;
while (i++ <1000){
data.push('' + i)
}
while (i++ < 20000){
data.push(''+i )
}
var start = window.performance.now()
data.sort(function(a,b){
if (a == null || a == undefined)
return 1;
else if ( b == null || b == undefined)
return -1;
return (parseInt(a) - parseInt(b));
})
$('#time0').html($('#time0').html() + (window.performance.now() - start))
data = []
var i = 0;
while (i++ <1000){
data.push('' + i)
}
while (i++ < 20000){
data.push(null )
}
var start = window.performance.now()
data.sort(function(a,b){
if (a == '' || a === null || a == undefined)
return 1;
else if ( a == '' || b === null || b == undefined)
return -1;
return (parseInt(a) - parseInt(b));
})
$('#time1').html($('#time1').html() + (window.performance.now() - start))
data = []
var i = 0;
while (i++ <1000){
data.push('' + i)
}
while (i++ < 20000){
data.push('' )
}
var start = window.performance.now()
data.sort(function(a,b){
if ( a == null || a == undefined)
return 1;
else if ( b == null || b == undefined)
return -1;
return (parseInt(a) - parseInt(b));
})
$('#time2').html($('#time2').html() +( window.performance.now() - start))
data = []
var i = 0;
while (i++ <1000){
data.push('' + i)
}
while (i++ < 20000){
data.push('' )
}
var start = window.performance.now()
data.sort(function(a,b){
if (a == '' || a == null || a == undefined)
return 1;
else if (b == '' || b == null || b == undefined)
return -1;
return (parseInt(a) - parseInt(b));
})
$('#time3').html($('#time3').html() +( window.performance.now() - start))
In order to ensure that your comparator will always return a logical answer for every pair of values, you'll have to add the case for when both values are empty:
data.sort(function(a,b){
var anull = (a == '' || a == null), bnull = (b == '' || b == null);
if (anull && bnull)
return 0;
if (anull)
return 1;
if (bnull)
return -1;
return (parseInt(a) - parseInt(b));
})
Note that you don't need an explicit compare to both null and undefined; comparing == null is exactly the same as comparing === null and === undefined.
My making sure you tell the sort algorithm that when both values are empty they can be left alone (by returning 0), you avoid it thrashing back and forth in some weird cases.
Another thing that might speed things up would be to make a single pass through the array to convert all the empty entries to some single value (maybe null; doesn't matter) and all the non-empty entries to actual numbers. That way your sort won't be paying the price of converting the strings to numbers over and over again (that is, all the calls to parseInt()). If you want the array to be strings, you can always convert it back in a subsequent single pass.

How can I loop through two arrays comparing values in 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)

Categories