This question already has answers here:
Get the last item in an array
(59 answers)
Closed 6 days ago.
I have a Javascript array, full_range:
const range1 = _.range(1, 10, 0.5);
const range2 = _.range(10, 100, 5);
const range3 = _.range(100, 1000, 50);
const range4 = _.range(1000, 10000, 500);
const range5 = _.range(10000, 105000, 5000);
const full_range = range1.concat(range2).concat(range3).concat(range4).concat(range5);
I then loop over this array and populate another array.
var transY= [];
var transX= [];
for(let i = 0; i < full_range.length; i++){
let y = getTrans(full_range[i], dampingFactor, natFreq); //returns a float
transY.push(y);
transX.push(parseFloat(full_range[i]));
}
The result is then returned to another function where:
console.log(transX); //Correct: Prints Array of 91 length (although the numbers with //decimals are at the end for some reason
console.log(transY); //Correct: Prints Array of 91 length
console.log("first");
console.log(transX[0]); //Correct: Prints 1
console.log("Last");
console.log(transX[-1]); //Incorrect: Prints "undefined instead of the last item
let xd = transX.pop();
console.log("xd:" + xd); //Works and correctly prints the last item in transX
The goal is to graph this dataset on a BokehJS graph, which does weird things when the last value is undefined.
Why is "undefined" being treated as an array element using slicing, but not when using pop()?
How would I be able to get the array without the undefined element?
Negative array indexing (with bracket notation) is not supported in JavaScript. However, you can use Array#at with negative indexes.
let arr = [1,2,3];
console.log(arr[-1]); // wrong
console.log(arr.at(-1)); // get last element
Related
This question already has answers here:
Split array into chunks
(73 answers)
Closed 1 year ago.
I have the js code below:
let splits = 23;
let outer_bound_value = 0;
let data = //this is an array of a large number of predefined objects (10,200+)
for (i = 0; i < data.length; i = i + outer_bound_value) {
outer_bound_value = data.length / splits;
let split_arr = array.slice(i, i + outer_bound_value);
}
The desired outcome of this code is to be able to split the mega array into smaller arrays based on what the value of splits is (if splits is 5, split the large array into 5 sections). I think the approach I have above works but it is dependent on splits being able to be go into the length of the object and it could cause outofbounds errors. Anyone have a more efficient way to do what I am trying to do?
First divide the array by the amount of splits you want.
Normally I would use a new Set() as it is much faster than splitting arrays with slice however I have no idea what type of data you have in your arrays, Sets are unique when it comes to ints.
we use recursion and destructuring to return the sliced array. this will return you multiple arrays into the array length/splits.
const splits = 23;
const data = new Array(10000);
const chunkValue = Math.floor(data.length/splits);
function chunkArray(array, size) {
if(array.length <= size){
return [array]
}
return [array.slice(0,size), ...chunkArray(array.slice(size), size)]
}
const newArrays = chunkArray(data, chunkValue)
This question already has answers here:
JavaScript - why Array.prototype.fill actually fills a "pointer" of object when filling anything like 'new Object()'
(4 answers)
Closed 1 year ago.
So I have a matrix A, of dimension n*n, initialized with Array.fill() like so.
var A = new Array(n).fill(new Array(n).fill(0))
That's cool and all however if I try to modify one of its values, the whole column modifies instead.
A[2][3] = 1 modifies the whole column 3.
Example snippet :
var n = 4;
var A = new Array(n).fill(new Array(n).fill(0));
console.log(JSON.stringify(A));
A[2][2] = 4;
console.log(JSON.stringify(A)); // ...
Why is that? o.O
That is bacause your first Array.fill call is using the same array reference to fill those 4 spots and only one inner array is created. So instead of first fill call you could use Array.from which is going to create new array for every spot.
var n = 4;
var A = Array.from(new Array(n), () => new Array(n).fill(0))
console.log(JSON.stringify(A));
A[2][2] = 4;
console.log(JSON.stringify(A)); // ..
Per MDN, Array.fill
If the first parameter is an object, each slot in the array will reference that object.
That is if the value you're filling the array with is an object, all elements will reference the same object and not a copy of the array
const n = 4;
const array = new Array(n);
for (let i = 0; i < n; i++) array[i] = new Array(n).fill(0);
console.log(JSON.stringify(array));
array[2][2] = 4;
console.log(JSON.stringify(array));
This question already has answers here:
Length of a JavaScript associative array
(4 answers)
JavaScript array length issue [duplicate]
(2 answers)
Closed 4 years ago.
I am creating an Array of days between 2 given dates, the keys should be formatted as DD/MM/YYYY and the values should be numbers (prices set for each date)
It seems to work because the Array contains the values I give it (via a date picker) but I can not loop through this Array, probably because it's length returns 0 even though it contains elements
Here is a screenshot of the console log statement
Here is the code that creates the Array
var arrayOfDatesBetween = new Array();
// daysBetween = integer representing the count of days between the chosen dates
for (let i = 0; i < daysBetween; i++) {
// just add one day on each iteration but keep count of the first
let q = i === 0 ? i : 1;
let _date = _dateIn.setDate(_dateIn.getDate()+q);
// lcsgDate() formats the date as I need it: DD/MM/YYYY
let __date = lcsgDate(_date);
// getDatePrice() gets the price for the given date by searching into another Array of date:price
arrayOfDatesBetween[__date] = getDatePrice(__date);
}
// result
console.log(arrayOfDatesBetween);
I confirm that changing arrayOfDatesBetween from Array to Object solved the issue and I can now have non-integers as keys, just as I needed, Thanks for commenting and pointing me to the right direction
let arr = [1,2,3]
arr['someCustomDate'] = 'someCustomData'
console.log(arr) // [1,2,3]
console.log(arr['someCustomDate'])
You code is essentially same as above, you're defining the property of an array instead of pushing them into the array.
To handle in your situation, you have two options:
1: for every element of your array, create an object and push them into your array like below:
var arrayOfDatesBetween = new Array();
// daysBetween = integer representing the count of days between the chosen dates
for (let i = 0; i < daysBetween; i++) {
// just add one day on each iteration but keep count of the first
let q = i === 0 ? i : 1;
let _date = _dateIn.setDate(_dateIn.getDate()+q);
// lcsgDate() formats the date as I need it: DD/MM/YYYY
let __date = lcsgDate(_date);
// getDatePrice() gets the price for the given date by searching into another Array of date:price
//HERE <=======
let newObjectElement = { date: __date, price: getDatePrice(__date)};
//arrayOfDatesBetween[__date] = getDatePrice(__date);
arrayOfDatesBetween.push(newObjectElement);
}
// result
console.log(arrayOfDatesBetween);
2: Remain your code, but using Object.keys to loop over __date.
Highly recommended to pick option 1 because thats the sole reason to use Array instead of pushing element as a key
I'm posting this question because I am trying to make a function that allows someone to create a multi-dim array. So, the user inputs an array of numbers which are the dimensions of the array (e.g entering [2, 4, 3] would output a 2x4x3 multi-dim array)
I have spent a couple of hours trying to imagine an algorithm that can do this in JS and I came up with this:
Note: I use Node.js v9.11.1
function generate(dimensions) {
// SA = sub-array (I will use this several times here)
// This array will store every SAs of the multi-dim array
// E.g for a 2x4x3 array, it will store a 2-item array, a 4-item array and a 3-item array
var arrays = []
// This fills `arrays` with the SAs
for (var i = 0; i < dimensions.length; i++) arrays.push(new Array(dimensions[i]).slice(0))
// Here it gets a bit complex (at least for me!)
// So what we do is that for each SA (except last), we fill it with copies of the current+1 SA
// So the SA at index 1 will be filled with copies of the array at index 2
// And the array at index 0 will be filled with arrays of index 1 (which was already filled because our for loop starts from the end)
// The array at index 0 is our final multi-dim array
// Goes from the before last SA to the first
for (var current = dimensions.length-2; current !== -1; current--) {
// Fills the current SA with index+1 SA
for (var i = 0; i < arrays[current].length; i++) arrays[current][i] = arrays[current+1].slice(0)
}
// Returns first array, the complete one
return arrays[0].slice(0)
}
My problem is that even if the array is well generated, some SA are passed by reference and not by value so when I do
my_array = generate([2, 4, 3])
my_array[1][2][1] = "hi!" // Fill a random place with "hi!"
Then when I do console.log(my_array), some other cases of the multi-dim array are filled with the same value.
This means that somewhere, an array is passed by reference rather than passed by value which is strange
because I checked the code multiple times and I don't find where this could come from (I use the Array.slice()
method to "copy" the array)
Have I missed something huge?
Your help would be rather appreciated!
To be honest, not sure how your trying to create your mult-dim array,..
But the first thing that springs to mind when seeing something like this, is recursion.
eg..
function generate(dimensions) {
if (!dimensions.length) throw new Error("no dims?");
const dimsize = dimensions[0];
if (dimensions.length === 1) {
return new Array(dimsize).fill(null);
}
const ret = [];
const subdims = dimensions.slice(1);
for (let l = 0; l < dimsize; l+= 1)
ret.push(generate(subdims));
return ret;
}
const my_array = generate([2, 4, 3])
my_array[1][2][1] = "hi!"
console.log(my_array);
I come up with this:
function generate(dims) {
if(dims.length > 0) {
let array = new Array(dims[0]).fill(0);
let childDims = dims.slice();
childDims.shift();
return array.map((el) => {
return generate(childDims);
});
} else return 0;
}
let foo = generate([2, 3, 2]);
foo[0][0][1] = 'hmmmm';
console.log(foo);
Also using recursion to create multidimensional array. But when creating arrays as You saw, have to be carefull about not passing references but real copies of arrays. Slice() will give You only shallow copy.
I want to make a variable length array in Javascript.
Is this possible. A quick google search for "Javascript variable length array" doesn't seem to yield anything, which would be surprising if it were possible to do this.
Should I instead have a String that I keep appending to with a separator character instead, or is there a better way to get a varible length array-like variable.
Javascript arrays are not fixed-length; you can do anything you want to at any index.
In particular, you're probably looking for the push method:
var arr = [];
arr.push(2); //Add an element
arr.push("abc"); //Not necessarily a good idea.
arr[0] = 3; //Change an existing element
arr[2] = 100; //Add an element
arr.pop(); //Returns 100, and removes it from the array
For more information, see the documentation.
Yes, variable-length arrays are possible with Javascript's Array prototype. As SLaks noted, you can use .push() and .pop() to add and remove items from the end of the array respectively and the array's length property will increase and decrease by 1 respectively each time.
You can also set the value of a specific index in an array like so:
const arr = [];
arr[100] = 'test';
console.log(arr[100]); // 'test'
console.log(arr.length); // 101
console.log(arr[99]); // undefined
Every other array index besides index 100 will be undefined.
You can also adjust the array's length by simply setting the array's length property, like so:
const arr = [];
arr[100] = 'test';
arr.length = 1000;
console.log(arr[100]); // 'test'
console.log(arr.length); // 1000
Or...
const arr = [];
arr[100] = 'test';
console.log(arr.length); // 101
arr.length -= 10;
console.log(arr.length); // 91
console.log(arr[100]); // undefined
The maximum value that an array's length property can be is 4,294,967,295. Interestingly though, you can set values of an array at indices larger than 4,294,967,295:
const arr1 = [];
const arr2 = [];
arr1[4294967294] = 'wow';
arr2[4294967295] = 'ok?';
console.log(arr1[4294967294]); // 'wow'
console.log(arr1.length); // 4294967295
console.log(arr2[4294967295]); // 'ok?'
console.log(arr2.length); // 0
If you try to set length a number larger than 4,294,967,295 it will throw a RangeError:
const arr = [];
arr.length = 4294967296;
console.log(arr.length); // RangeError: Invalid array length
You can also use the Array() constructor.
const desiredLength = 5; // could be dynamically generated
const list = new Array(desiredLength); // will be length 5
One caveat is that you will be unable to map the initial elements by using Array(n).map(). Instead, you can use Array.from() (Documentation).
const desiredLength = 5; // could be dynamically generated
const passkeys = Array.from(Array(desiredLength), () => {
return Math.random().toString(32).substring(2, 10);
});