Check if an array element/item is undefined - javascript

How do I add to z only if y exists without adding a zero instead?
var x=[-1,2,44,6];
var y=[33,2,1]; //a shorter array where y[3] does not exist
var z=[];
var i=x.length;
while(i--){
z[i]=x[i]+y[i];
}
When I know that all the x's exist but i do not know if there is a y for each x.
Also the problem may include more arrays of varying undetermined sizes (not just x and y, say t, u, v, w named arrays that may or may not have same lengths)
How would I loop through adding all arrays together without changing the loop, creating NaN or adding any zeros?
Can this be done inline?

You just need a if condition to check if the lengths of the array are equal.
if(x.length == y.length) {
var i = x.length;
while(i--)
z[i]=x[i]+y[i];
}

while (i--) {
z[i] = ((i > y.length - 1)? x[i] : x[i] + y[i]);
}

var x=[-1,2,44,6];
var y=[33,2,1]; //a shorter array where y[3] does not exist
var z=[];
var i=Math.max(y.length, x.length);
while(i--){
if (typeof y[i] !== 'undefined' && x[i] !== 'undefined') {
z[i]=x[i]+y[i];
}
}

This works best
var y=[];
var x=[1];
var z=(x[0]+(y[0]?y[0]:null)||undefined);
y has no existing values. x has a value we know exists. I can safely add x to z and safely add null to z if y does not exist. For whatever reason if everything were to go null then I end up with z undefined.

Related

Combine an array with other arrays, push each combination Javascript

I'm trying to take an array, and compare each value of that array to the next value in the array. When I run my code, components that should match with more than one array only return one match, instead of all of them. I'm probably doing something wrong somewhere, but for the life of my I don't seem to be able to figure it out.
This is my code:
INPUT
minterms = [["4",[0,1,0,0]],
["8",[1,0,0,0]],
["9",[1,0,0,1]],
["10",[1,0,1,0]],
["12",[1,1,0,0]],
["11",[1,0,1,1]],
["14",[1,1,1,0]],
["15",[1,1,1,1]]];
Function
function combineMinterms(minterms) {
var match = 0;
var count;
var loc;
var newMin = [];
var newMiny = [];
var used = new Array(minterms.length);
//First Component
for (x = 0; x < minterms.length; x++) {
if(minterms[x][1][minterms[x][1].length - 1] == "*") {
newMin.push(minterms[x].slice());
continue;
};
//Second Component
for (y = x + 1; y < minterms.length; y++) {
count = 0;
//Compare each value
for (h = 0; h < minterms[x][1].length; h++) {
if (minterms[x][1][h] != minterms[y][1][h]) {
count++;
loc = h;
}
if (count >= 2) {break; };
}
//If only one difference, push to new
if (count === 1) {
newMin.push(minterms[x].slice());
newMiny = minterms[y].slice();
newMin[match][1][loc] = "-";
while(newMin[match][0].charAt(0) === 'd') {
newMin[match][0] = newMin[match][0].substr(1);
}
while(newMiny[0].charAt(0) === 'd') {
newMiny[0] = newMiny[0].substr(1);
}
newMin[match][0] += "," + newMiny[0];
used[x] = 1;
used[y] = 1;
match++;
continue;
}
}
//If never used, push to new
if(used[x] != 1) {
newMin.push(minterms[x].slice());
newMin[match][1].push("*");
match++;
}
}
return newMin;
}
Desired Output
newMin = [["4,12",[-,1,0,0]],
["8,9",[1,0,0,-]],
["8,10",[1,0,-,0]],
["8,12",[1,-,0,0]],
["9,11",[1,0,-,1]],
["10,11",[1,0,1,-]],
["10,14",[1,-,1,0]],
["12,14",[1,1,-,0]],
["11,15",[1,-,1,1]],
["14,15",[1,1,1,-]]];
It will combine term 8, with 9 but won't continue to combine term 8 with 10, 12
Thanks in advance for the help.
Array.prototype.slice performs a shallow copy.
Each entry in minterms is an array of a string and a nested array.
When you slice the entry, you get a new array with a copy of the string and a copy of the Array object reference. But that copy of the Array reference still points to the array contained in an element of minterms.
When you update the nested array
newMin[match][1][loc] = "-";
you are updating the nested array within the input. I never fathomed the logic of what you are doing, but I believe this is the problem, with solution of cloning the nested array (as well) when cloning an input array element.
A secondary issue you will probably wish to fix is that not all variables were declared: var x,y,h; or equivalent inline declarations are missing.
let minterms = [4,8,9,10,12,11,14,15];
let newMin = [];
minterms.map((value, index) =>{
minterms.reduce((accumulator, currentValue, currentIndex, array) => {
accumulator = value;
let out = (accumulator ^ currentValue).toString(2);
if(out.split('').filter(n=>n==="1").length == 1) newMin.push([value, currentValue]);
}, value);
});
console.log(newMin);
There is a better approach (in 10 lines of code). Since you're working with binary representations, you might want to consider using BitWise operators. When coupled with array operators it makes most of this straight forward.
For instance:
Given a match means only a single bit differs between two binary numbers:
The bitwise XOR operator returns 1 for each bit that doesn't match. So:
0100 XOR 1000 results in 1000
Now, we need to count the number of '1' digits in the binary number returned. We can use the length property of an array to do this. To turn 1000 into an array, first we turn the binary into a string:
The binary representation of the integer 4 is easily retrieved with:
num.toString(2)
So if num === 4, the output above is the string "0100".
Now we use str.split() to turn the string into an array. Remove everything from the array that is not a '1'. Now simply get the length property. If the length === 1, it is a match.
I put together a solution like this for you. It is close to your use case. I didn't use the funny dash style in the output because that was not part of your question.
https://jsbin.com/xezuwax/edit?js,console

multidimensional array indexOf not working js

I'm trying to find an index of a number in a 2d array, but console gives out
Uncaught TypeError: block[((a * 10) + c)].indexOf is not a function
I think it has something to do with the way of accessing the array element, but can't seem to find the problem.
Here's the code.
var block = [];
var temp;
var del;
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
temp = parseInt(prompt("enter element number " + b + " of row number " + a));
console.log(temp);
if(temp>0){
block[a*10+b] = temp;
}else{
block[a*10+b] = [1,2,3,4,5,6,7,8,9];
}
// console.log(block[a*10+b]);
}
}
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
if(typeof(block[a][b]) == "number"){
for(var c = 0;c < 9;c++){
if(c != b){
del = block[a*10+c].indexOf(b);
block[a*10+c].splice(del,1);
}
}
}
}
}
You have a mix of data types assigned to the block array. When the user enters a value that is not numeric, you assign indeed a nested array to one of the block elements, but not so when the user enters a valid number.
From what I think you are doing (a Sudoko game?) this might be intended: the numbers are known values in the grid, the nested arrays represent a list of values that are still possible at that particular cell.
But then in the second part of your code, you should check in which of the two cases you are, as you only want to remove array elements if the value you are looking at is indeed an array. This test you can do with Array.isArray().
There are also some other issues in the second part of your script:
The expression block[a][b] is not consistent with how you have filled that array: it should be block[a*10+b] to be consistent.
the b in .indexOf(b) is wrong: you are not looking for that value, but for block[a*10+b].
the splice() is always executed, even if the indexOf returned -1. This leads to an undesired effect, because if the first argument to splice() is negative, the index really is counted from the end of the array, and still an element is removed from the array. This should not happen: you should only execute the splice if the indexOf result is non-negative.
Below I have put a working version, but in order to avoid the almost endless prompts, I have provided this snippet with a textarea where you can input the complete 9x9 grid in one go, and then press a button to start the execution of your code:
document.querySelector('button').onclick = function () {
var block = [];
var temp;
var del;
var text = document.querySelector('textarea').value.replace(/\s+/g, '');
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
temp = parseInt(text[a*9+b]); // <-- get char from text area
if(temp>0){
block[a*10+b] = temp;
}else{
block[a*10+b] = [1,2,3,4,5,6,7,8,9];
}
}
}
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
var num = block[a*10+b]; // <-- get content, fix the index issue
if(typeof num == "number"){
for(var c = 0;c < 9;c++){
if(c != b && Array.isArray(block[a*10+c])){ //<-- add array-test
del = block[a*10+c].indexOf(num); // <-- not b, but num
if (del > -1) // <-- only splice when found
block[a*10+c].splice(del,1);
}
}
}
}
}
document.querySelector('pre').textContent = 'block='+ JSON.stringify(block);
};
<textarea rows=9>
53..7....
6..195...
.98....6.
8...6...3
4..8.3..1
7...2...6
.6....28.
...419..5
....8..79
</textarea>
<button>Process</button>
<pre></pre>
Note that there are elements in block which remain null. I suppose you intended this: as you multiply a with 10, and only store 9 values per "row", there is always one index that remains untouched.
I haven't looked over your second for loop, but you can try applying similar logic there as in the snippet I've provided. The issue is that you need to create a temporary array inside the outer for loop over values of a (but NOT inside the inner, nested for loop over values of b). Inside the for loop for values of b, then, you need to push something into that temporary array (which I called temp). Then, outside of the b for loop, but before the next iteration of a, push that temporary array temp to the block array. In this way, you will generate a 2D array.
var block = [];
var del;
for(var a = 0; a < 9; a++) {
let temp = [];
for(var b = 0; b < 9; b++) {
let num = parseInt(prompt(`Enter element ${b} of row ${a}:`));
if (num > 0) {
temp.push(num);
} else {
// block[a*10+b] = [1,2,3,4,5,6,7,8,9];
temp.push(b);
}
}
block.push(temp);
}

How to push multiple zeros to an already existing array

I found on this link how to create arrays with a chosen number of zeros.
Most efficient way to create a zero filled JavaScript array?
But my question is, imagine i already have a array
var a = ['hihi','haha']
how can i add 12 zeros after my two first elements ? So that it becomes :
a = ['hihi','haha',0,0,0,0,0,0,0,0,0,0,0,0];
of course I could go for a
for(var i = 0; i < 12, i++){
a.push(0);
}
but is there a one line method ? something like
a.push(6*[0]);
You can use Array.prototype.concat() and Array.prototype.fill()
Create an array with size 12 and fill 0 by using Array.prototype.fill()
Then concatenate with existing array using Array.prototype.concat()
var a = ['hihi', 'haha'].concat(Array(12).fill(0));
document.write('<pre>' + JSON.stringify(a, null, 3) + '</pre>');
You could for instance use a solution from the answer you link to create an array of twelve zeroes, and then use the Array.prototype.concat function to create the array you need.
var zeroes = Array.apply(null, Array(12)).map(Number.prototype.valueOf, 0);
var laughters = ['hihi', 'haha'];
var combined = laughters.concat(zeroes);
function fillArray(value, len) {
if (len == 0) return [];
var a = [value];
while (a.length * 2 <= len) a = a.concat(a);
if (a.length < len) a = a.concat(a.slice(0, len - a.length));
return a;
}
It doubles the array in each iteration, so it can create a really large array with few iterations.
In short, take your array and perform a concat with the answer you mentioned.
var a = ['hihi','haha'].concat(Array.apply(null, Array(12)).map(Number.prototype.valueOf,0);)
Must de 0 be an int or a string?
And why do you want to add 12 zeros?
What do you have tried so far?
Just an easy sample,
var a = ['hi', 'ha'];
for(var i = 0; 14 > a.length; i++){
a.push(0);
}

Can someone explain what's going on in this for loop?

Also please include a tracetable that shows the values of each variable at each position. Thanks. When it returns true, it says that the array is a palindrome. When it returns false, it says that the array is not a palindrome. The code works, but I just need an explanation of why or how it works.
var x = readNumberOfEntries();
var w = new Array(x);
for (var y = 0; y < x; y++) {
var z = Number(prompt("Enter entry"));
w[y] = z;
}
var r = w.length;
for (var i = 0; i < (r/2); i++) {
if (w[i] !== w [r-1-i]) {
return false;
}
return true;
}
}
First for-loop fills an array of length x with user entered values.
Second for-loop checks for array like this [1,2,3,3,2,1].
So it checks wether the array is reversev in the second half.
Though because of the return the for-loop will be canceled at first run.
So if the first entry of the array equals the last it will return true, otherwise false.

Determining array's coordinates with a string

The title is already saying. I need to determinate array's coordinates with a string.
As for example: if I want to move the value 1 to the right twice, I'm going to write in my seed variable: "rr". The r means that the value will be moved one index to the right.
In this link: http://jsfiddle.net/Kike/hVczZ/ I'm explaining better.
This works if the movement is possible :
for(var t = array.length; t >= 0; t--){
if(array[t]==1){
move(t,seed);
break;
}
}
function move(index,movements){
var size=5;
var x=index % size;
var y= Math.floor(index / size);
for(var i=0;i<movements.length;i++){
var pos=movements[i];
if(pos=='r'){
if(x+1 == size){
x=0;
y+=1;
}else{x+=1;}
}else if(pos=='l'){
if(x==0){
y-=1;
x=size-1;
}else{x-=1;}
}else if(pos=='u'){
y-=1;
}else if(pos=='d'){
y+=1;
}
}
array[index]=0;
array[size*y+x]=1;
}
console.log(array) // 1 is in fourth position

Categories

Resources