Can't add to javascript array in loop - javascript

I'm having some issues with the following code:
var tmpArray = new Array();
for(var n in fnlArray){
if(fnlArray[n] == largest.val){
alert(fnlArray[n] +"-"+ largest.val);
tmpArray[n] = fnlArray[n];
}
}
fnlArray contents is:
fnlArray['result1'] = 1;
fnlArray['result2'] = 2;
fnlArray['result3'] = 2;
fnlArray['result4'] = 2;
and largest.val = 2;
The issue I'm having is the alert gets fired so I would expect to end up with tmpArray with the following:
tmpArray['result2'] = 2;
tmpArray['result3'] = 2;
tmpArray['result4'] = 2;
But the array (tmpArray) is always empty. Is this an issue with adding items to the array dynamically within a loop?

var tmpArray = new Array(); should be:
var tmpArray = {};
Your tmpArray object is not a index array, so you have to use object literals.
var tmpArray = {};
for(var n in fnlArray){
if(fnlArray[n] == largest.val){
tmpArray[n] = fnlArray[n];
}
}
alert(JSON.stringify(tmpArray)); //Prints: {"result2":2,"result3":2,"result4":2}
Demo: http://jsfiddle.net/QhFGF/

Related

How to combine arrays according indexes in javascript?

I have two 2d arrays:
var ar1 = [];
var ar1[0] = [];
var ar1[0][0] = 1;
var ar1[0][1] = 2;
var ar1[1] = [];
var ar1[1][0] = 3;
var ar1[1][1] = 4;
var ar2 = [];
var ar2[0] = [];
var ar2[0][3] = 5;
var ar2[0][4] = 6;
var ar2[1] = [];
var ar2[1][5] = 7;
var ar2[1][6] = 8;
How can I get the combined array that will look like:
var ar1[0][0] = 1;
var ar1[0][1] = 2;
var ar1[1][0] = 3;
var ar1[1][1] = 4;
var ar1[0][3] = 5;
var ar1[0][4] = 6;
var ar1[1][5] = 7;
var ar1[1][6] = 8;
I tried:
ar1.push(ar2);
but this puts whole ar2 to the first empty row of ar1.
One possibility is to forEach over the second array, and Object.assign each subarray onto the appropriate index in the first:
var ar1 = [];
ar1[0] = [];
ar1[0][0] = 1;
ar1[0][1] = 2;
ar1[1] = [];
ar1[1][0] = 3;
ar1[1][1] = 4;
var ar2 = [];
ar2[0] = [];
ar2[0][3] = 5;
ar2[0][4] = 6;
ar2[1] = [];
ar2[1][5] = 7;
ar2[1][6] = 8;
ar2.forEach((subarr2, i) => {
Object.assign(ar1[i], subarr2);
});
console.log(ar1);
Do note that var should only be used when declaring a new variable name for the first time - when assigning to an existing variable, omit it. (Also, sparse arrays are rarely a good idea)
You could iterate the second array and assign all values to the first array. For not given array in the second level take an array as default.
var ar1 = [],
ar2 = [];
ar1[0] = [];
ar1[0][0] = 1;
ar1[0][1] = 2;
ar1[1] = [];
ar1[1][0] = 3;
ar1[1][1] = 4;
ar2[0] = [];
ar2[0][3] = 5;
ar2[0][4] = 6;
ar2[1] = [];
ar2[1][5] = 7;
ar2[1][6] = 8;
ar2.forEach((a, i) => {
ar1[i] = ar1[i] || [];
a.forEach((v, j) => ar1[i][j] = v);
});
console.log(ar1);

Defining a 3D array in JavaScript

I tried to define a 3D array on Google Sheet, but even though I'm using the .slice() method it keeps passing the array by reference.
var temp = [];
for (var a = 0; a<archetypesAll.length; a++) {temp[a] = [0, a].slice();};
var archRank = [];
for (var a = 0; a<21; a++) {archRank[a]= temp.slice();};
archRank[2][1][0] = 'Test';
I want to edit a single element of the matrix but instead the code above just fills every row with the exact same value ('Test'):
3DMatrix[x][1][0] = 'Test'
You can't just copy a multidimensional array by calling slice at the top level, because that will not deep-copy the whole. You have to write your own deepCopy methid, like this:
function allocate(mainDim, ...dims) {
const result = new Array(mainDim);
for (let i = 0; i < result.length; i++) {
result[i] = dims.length > 0 ? allocate(...dims) : 0;
}
return result;
}
function deepCopy(matrix, dims) {
return dims > 1 ? matrix.map(row => deepCopy(row, dims - 1)) : matrix.slice();
}
function test() {
const mx1 = allocate(3,2,2);
mx1[2][1][0] = "Test";
console.log(JSON.stringify(mx1));
const mx2 = deepCopy(mx1, 3);
mx2[2][1][0] = "Copied";
console.log(JSON.stringify(mx1));
console.log(JSON.stringify(mx2));
}
test();
var array = ["Test", "Test"];
var array3d = [[array.slice(0)],[[array.slice(0)]]];
array3d[0][0][0] = "Changed";
console.log(JSON.stringify(array3d)); //[[["Changed","Test"]],[[["Test","Test"]]]]
Try with this instead of slice to get a new array instead of reference:
var temp = [];
for (var a = 0; a < archetypesAll.length; a++) {
temp[a] = JSON.parse(JSON.stringify([0, a]));
}
var archRank = [];
for (var a = 0; a < 21; a++) {
archRank[a]= temp.slice();
}
archRank[2][1][0] = 'Test';

XYZ dimensional array

Why is this code shown array[7][0] is undefined when it should have a value?
var tnotes = [];
var index = 0;
for (var i = 0; i < 14; i++) {
tnotes[i] = [];
}
var tx = 'B4';
var notes=['B5','A5','G5','F5','E5','D5','C5','B4','A4','G4','F4','E4','D4','C4']
var getNotes = notes.indexOf(tx);
if (getNotes != -1) {
tnotes[getNotes][index][] = new Array(20)
tnotes[getNotes][index][0] = tx //B4
tnotes[getNotes][index][2] = '3sec'
index++
}
console.log(tnotes[7][0])
You simply have a syntax error in defining one of your sub-arrays. The following line is incorrect:
tnotes[getNotes][index][] = new Array(20)
You are introducing a third-dimension of your tnotes array without it being defined
It should be:
tnotes[getNotes][index] = [];
Or if you really need the size parameter:
tnotes[getNotes][index] = new Array(20);
After this, tnotes[7][0] should no longer be undefined. Also, please do yourself a favor and make sure you use semi-colons consistently, it's good practice and can save you many-a-headache.
Corrected code:
var tnotes = [];
var index = 0;
for (var i = 0; i < 14; i++) {
tnotes[i] = [];
}
var tx = 'B4';
var notes = ['B5','A5','G5','F5','E5','D5','C5','B4','A4','G4','F4','E4','D4','C4'];
var getNotes = notes.indexOf(tx);
if (getNotes != -1) {
tnotes[getNotes][index] = [];
tnotes[getNotes][index][0] = tx; //B4
tnotes[getNotes][index][2] = '3sec';
index++;
}
console.log(tnotes[7][0]);

Change Array Formatting

How to change this Javascript array format:
var sample_data = ["af","16.63","al","11.58","dz","158.97"];
to this object format:
var sample_data = {"af":"16.63","al":"11.58","dz":"158.97"};
Could use Array.shift to do it too. No idea how it compares to other methods speed wise.
var sample_data = ["af","16.63","al","11.58","dz","158.97"]; // source
var data = sample_data.slice(); // clone the data
sample_data = {};
while (data.length > 1) {
sample_data[data.shift()] = data.shift() || null;
}
var d = {}; // a temporary object
for (var i = 0; i < sample_data.length; i += 2) {
// iterate over sample_data with a step width of 2
// and set the the data in the temp. object
d[sample_data[i]] = sample_data[i+1];
}
sample_data = d;
the code for it will look like this
var sample_data = ["af","16.63","al","11.58","dz","158.97"];
var tmp = sample_data;
sample_data = {};
for (var i = 0; i < tmp.length / 2; i++)
sample_data[tmp[i * 2]] = tmp[i * 2 + 1];
EDIT
Keep in mind.
var arr = []; // This is an array
var obj = {}; // This is an object! Not array.

Find missing element by comparing 2 2D-Arrays in Javascript

A few days ago I posted a thread asking on how to find the missing element when passing a method 2 JS arrays. As you can see here. I've been trying to figure out now how to modify the method so that instead of passing it 2 Arrays you pass it 2 2D-Arrays... Having some trouble though:
/*var sml = new Array();
sml[0] = new Array("dean","22");
sml[1] = new Array("james","31");
sml[2] = new Array("ludwig","35");
var lrg = new Array();
lrg[0] = new Array("dean","22");
lrg[1] = new Array("james","31");
lrg[2] = new Array("ludwig","35");
lrg[3] = new Array("kevin","23");
lrg[4] = new Array("elton","40");*/
var sml = new Array();
sml[0] = "dean";
sml[1] = "james";
sml[2] = "ludwig";
var lrg = new Array();
lrg[0] = "dean";
lrg[1] = "james";
lrg[2] = "ludwig";
lrg[3] = "kevin";
lrg[4] = "elton";
var deselected = findDeselectedItem(sml, lrg);
alert("Deselected Items: " + deselected[0]+", "+ deselected[1]);
// -------------------------------------------------------------- //
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItems = new Array();
// loop through previous array
for (var j = 0; j < PreviousArrSize; j++) {
// look for same thing in new array
if (CurrentArray.indexOf(PreviousArray[j]) == -1)
deselectedItems.push(PreviousArray[j]);
}
if (deselectedItems.length != 0) {
return deselectedItems;
} else {
return null;
}
}​
Now if you run the above code it works perfectly, but if you go and uncomment the variable declarations on top that that pushes arrays ontop of the array, and then comment out the simple strings that get pushed on top of the array, it doesn't work as well... For instance:
var sml = new Array();
sml[0] = new Array("dean","22");
sml[1] = new Array("james","31");
sml[2] = new Array("ludwig","35");
var lrg = new Array();
lrg[0] = new Array("dean","22");
lrg[1] = new Array("james","31");
lrg[2] = new Array("ludwig","35");
lrg[3] = new Array("kevin","23");
lrg[4] = new Array("elton","40");
/*var sml = new Array();
sml[0] = "dean";
sml[1] = "james";
sml[2] = "ludwig";
var lrg = new Array();
lrg[0] = "dean";
lrg[1] = "james";
lrg[2] = "ludwig";
lrg[3] = "kevin";
lrg[4] = "elton";*/
var deselected = findDeselectedItem(sml, lrg);
alert("Deselected Items: " + deselected[0]+", "+ deselected[1]);
// -------------------------------------------------------------- //
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItems = new Array();
// loop through previous array
for (var j = 0; j < PreviousArrSize; j++) {
// look for same thing in new array
if (CurrentArray.indexOf(PreviousArray[j][0]) == -1)
deselectedItems.push(PreviousArray[j][0]);
}
if (deselectedItems.length != 0) {
return deselectedItems;
} else {
return null;
}
}​
The method returns 2 completely wrong values. PS - I'm not interested in the "numbers" just yet, just the "names" for now...
Your CurrentArray is 2-dimensional and indexOf compares Arrays but not first elements of that Arrays. So you need to use:
for ( var i = 0; i < CurrentArray.length; ++i){
if (CurrentArray[i][0] == PreviousArray[j][0]){
deselectedItems.push(PreviousArray[j][0]);
break;
}
}
Instead of
if (CurrentArray.indexOf(PreviousArray[j][0]) == -1)
deselectedItems.push(PreviousArray[j][0]);
You could also rearrange the array like this:
var sml = {};
sml["dean"] = 22;
sml["james"] = 31;
sml["ludwig"] = 35;
var lrg = {};
lrg["dean"] = 22;
lrg["james"] = 31;
lrg["ludwig"] = 35;
lrg["kevin"] = 23;
lrg["elton"] = 40;
and use:
function findDeselectedItem(c,p){
ret=[];
for (var i in p){
if (p.hasOwnProperty(i)){
if ('undefined'===typeof c[i]) {
ret.push(i);
}
}
}
return ret;
}
alert(findDeselectedItem(sml, lrg));
Demo: http://jsfiddle.net/LsrCj/
indexOf function will check object equality in this case; to make it return something else than -1 you've to pass same 2D array instances to sml and lrg.
new Array("dean","22") === new Array("dean","22") //false
Keep the same instances (e.g. http://jsfiddle.net/3TQYz/) in both arrays or use your own indexOf test that would recursively check values of the array to make your case working.

Categories