Circumvent References when deleting Array Content in JavaScript - javascript

I'm implementing a simple logging mechanism by storing arrays as log entries in a single array.
The code works like this:
var myarr = new Array();
var secondarr = new Array(4,5,6);
myarr.push(secondarr);
secondarr.length=0;
secondarr.push(5,5,5);
myarr.push(secondarr);
secondarr.length=0;
//check
for(var i = 0; i < myarr.length; i++){
var str="";
for(var j = 0; j < myarr[i].length; j++)
str+=myarr[i][j]+" ";
console.log(str);
}
I'm creating my single array myarr, in which logentries are stored. The secondarr stores data to log. Because I don't want to create a new array each time I log something into myarr, I wanted to set back the secondarr through secondarr.length=0.
However this deletes everything out of myarr as well, because of references!
Is there a way to circumvent creating new arrays for each log? The method of course works if I push secondarr.slice(), but this results in multiple arrays, which I'm trying to avoid.

replace each secondarr.length=0; by secondarr=[];. The first instruction modifies the length property of the array referenced by secondarr. The second one makes that secondarr now refers to a new empty array.
In any case, you have to create a new array for each logentry you want to store.

Related

Dynamic Array pushing Vs Assigning to a Static Size Array: Time Complexity in JavaScript

I have a dynamic array as shown below:
const array1 = [];
for(let i = 0; i < 5; i++)
array1.push(i+1);
and another array:
let Array2 = Array(6); //Note here the size is 6 as compared to the array1 which has initial size as 5.
for(let i = 0; i < 5; i++)
Array2[i] = i+1;
Now I want to append an element to the last of the array as shown below:
array1.push(6);
Will the above operation will be O(n) as this process will result in array1 to be moved to a new array and then appending 6 at the end or will it just be O(1).
Also which declaration is better?
const array1 = []
and then adding the elements to it, or initializing an empty array (whose size is known) and then substituting in the elements one by one.
So here's the example for the same:
It is known that first five elements are coming from a for loop (which invokes another function) and the last element is coming from a function getElement as shown below:
Method 1:
const Array1 = [];
for(let i = 0; i < 5; i++)
Array1.push(getFirstFiveElements(i));
//Where getFirstFiveElements is another function
Array1.push(gettheSixthElement());
or Method 2:
const Array2 = Array(6);
for(let i = 0; i < 5; i++)
Array2[i] = getFirstFiveElements(i);
Array2[Array2.length - 1] = gettheSixthElement();
It's always better to initialize an array whose size is known. Because when you push elements onto an array that lacks the number of empty slots needed, behind the scenes JavaScript has to copy the existing underlying array into a new array twice the size of the old array. Therefore adding values to the array is not O(1) on average because sometimes it results in the entire array being copied. Whereas if you initialize the array with a known size, all additions to the array are O(1).
Why do we need to initialize the length?
Theoretically there is no need for this. It can even result in confusing behavior, because all tests that use the length to find out whether an array is empty or not will report that the array is not empty.
Some tests show that setting the initial length of large arrays can be more efficient if the array is filled afterwards, but the performance gain (if any) seem to differ from browser to browser.

updating a JSON objects value with a for loop in Java Script

I have an array of 11 objects which contain JSON data. I wrote a function in which a new key with a zero value is added to each of the objects. Now I want to update the value of the said key in all 11 objects. The data is stored in an array2 with 11 numbers. My for loop doesn't seem to work for this, and the only way to do it (so far) is to hard code it. Does anyone has a suggestion how this can be done?
The desired outcome would be this:
array[0].new_key = array2[0];
array[1].new_key = array2[1];
The first art of the function, before the for loop with j, is for adding the new key into the original array and that part works.
for (i = 0; i < array.length; i++) {
array.map(i => i.new_key = 0);
console.log(array)
for (j = 0; j < array2.length; j++) {
array[i].new_key = array2[j];
console.log(array)
}
}
}```
I split it into two functions, I realized that I made it too complicated and it didn't made sense. I wrote a second function that only updates all the key values, so indeed, I removed the inner loop as it was not needed. Thank you for the help.
.map() does not modify the original array:
The map() method creates a new array with the results of calling a
provided function on every element in the calling array.
You will want to get the result of the map by assigning it to a variable, and see what is happening there. Right now you don't do anything with it, so it will just disappear.
While the above is true for maps, in this case the original array is being modified as we access the object's properties and modify them there.

JS arrays 3 deep getting lost

Learing JS by game. and of course the simplist is a clicker :-)
OK, so I have had lots of help with this, but the array section is just not sinking in. JS arrays do not work like arrays I am used to. two part question:
1. Why does the following code keep saying weaponlevelIfo[0] undefined, when it is defined? Please explain your answer, don't just correct mine LOL
2. I am more interesting in populating the code at runtime
As stated, all the research I am coming across as well as videos, talk about static data, i.e. it is put in at programing level, not run time.
I have had a really patient community person that has tried to help me understand JS arrays, but I must be blind as I am not seeing it. I can do in in other language just fine. but JS? nope.
// produces weaponLevelNfo[weaponId][level][cost] and [goldperclick]
// weapon, level 1-9, cost/goldperclick on each level
var weaponLevelNfo = new Array(14); // Outter array comprised of weapons 0-14
function initGame() {
for (let i=0; i <= weaponLevelNfo.length; i++) {
weaponLevelNfo[i] = new Array(9); // create leves array under weaponid array
for (let j = 0; j < weaponLevelNfo[i].length; j++) {
// loop through each 9 levels changing as needed
weaponLevelNfo[i][j] = new Array(2); // create an object for readability
}
}
}
initGame();// added - forgot to add this in the original post (sorry)
weaponLevelNfo[0][0][2]=3;
console.log(weaponLevelNfo[0][0][2]);
// always gives me weaponLevelNfo[0] not defined
I prefer the results to be as such
weaponLevelNfo[x][y].cost,
weaponLevelNfo[x][y].incomePerClick,
but am quite happy with
weaponLevelNfo[x][y][z],
weaponLevelNfo[x][y][z],
But as you can see from the code, assigning them direct or at runtime, I get the not defined error
What is missing to allow me to assign these at run time?
Two issues:
You need to call initGame to create all those subarrays, otherwise weaponLevelNfo[0] is not defined and so weaponLevelNfo[0][0] will trigger the error you get.
Your outer loop performs one iteration too many (<=). Change:
for (let i=0; i <= weaponLevelNfo.length; i++) {
by
for (let i=0; i < weaponLevelNfo.length; i++) {
Without that change, the last iteration is actually adding an element to the array in slot i, and so the length of the array increases... the loop becomes infinit.
Note that there are shorter ways to define such a nested array. For instance:
var weaponLevelNfo = Array.from({length:14}, () => Array.from({length:9}, () => [0, 0]));
When you create an array in javascript with new Array(2) this is an array with two positions. In this example (new Array(2)), you can access it at index 0 and index 1. Consider the following:
var newArr = new Array(2);
You can then access the two positions by the following:
var position1 = newArr[0];
var position2 = newArr[1];
So when you try this:
var position = newArr[2];
This will throw an undefined exception.
You can change the end of your example code to this:
weaponLevelNfo[0][0][1]=3;
console.log(weaponLevelNfo[0][0][1]);
You define array with two elements Array(2) with indexes 0 and 1 but you use index 2.
To initialize multidimensional array filled by zeros (if not remove .fill(0)) use
[...Array(14)].map(x=>[...Array(9)].map(y=>Array(2).fill(0)));
let a=[...Array(14)].map(x=>[...Array(9)].map(y=>Array(2).fill(0)));
a[13][8][1]=3;
console.log('Last element value:',a[13][8][1]);
console.log(JSON.stringify(a));

Javascript array in array - first index is always overwritten

I have a problem with my JS function. For simplification, I want to fill an array (arr1) with n other arrays (arr2). In my loop I use a counter for the current postion in arr1 (cant use arr1.push for a reason). If I log all my arr2's in arr1 they are all the same, always the last one that was added. So I wrote a basic script to test it. I always log the first element and incement the counter.
I'm new to JS, is there some huge misunderstanding I don't get?
function test(){
var arr1 = [];
var arr2 = [];
var counter=1;
arr2[0]="first";
arr2[1]="first";
arr2[2]="first";
arr1[0]=arr2;
arr1[0].forEach(function(elem){console.log(elem);});
for (var i = 0; i < 10 ; i++) {
arr2[0]=counter;
arr2[1]=counter;
arr2[2]=counter;
arr1[counter]=arr2;
arr1[0].forEach(function(elem){console.log(elem);});
counter++;
}
}
<button onclick="test()">Click</button>
You can try to use the spread operator.
arr1[0]=[...arr2];
arr1[counter]=[...arr2];
An array is a reference type, so you always refer to the base, you don't put a copy of it inside of arr1 but a reference to the arr2.
You want a copy of arr2 to be assigned to arr1.
You can do this by creating a new Array, or more modern the ... spread operator
As Pointy said it, it just referenced the arr2 and doesn't create a copy.
So you need to
arr2=new Array();
at the beginning of the loop.

JavaScript Copy Array By Value

I have created an array and received another from a php file.
The data is fine but when i try to copy one array to another, it seems like when i change arr1 then arr2 is also changed.
It is being copied "by reference" and not "by value" as i need
I also tried slice() butit doesn't work, The variable does not being copied at all, not even "by reference" in that way.
// arr1[0] = "Hey";//this array is coming from another file and the data is fine
var arr2 = [];
arr2[0] = arr1[0];
arr2[0] += "1"; // right now arr1 and arr2 both has "Hey1" in them.
Any ideas?
Thank You
An array is an object in Javascript. As you might know objects are copied by reference. You could take a look here: What is the most efficient way to deep clone an object in JavaScript?
You can do a deep, rather than a shallow, copy of an array of strings like this:
var arr2 = [], i = 0;
for (i = 0; i < arr1.length; i++) {
arr2[i] = String(arr1[i]);
}
EDITED: oops, swapped deep and shallow.

Categories

Resources