I need help with making a 3-dimensional array, my objective is e.g:
Just for graphic illustration :-), see row below
[category: 1[subcategories: 1[subsubcategories: 1,2],2[subsubcategories: 3,4]]
In scenario above the user has selected:
category 1
subcategories: 1
subsubcategories: 1,2
subcategories: 2
subsubcategories: 3,4
I can then with these values create a string like: 1^1:1,2^2:3,4
Hope anyone understands :)
Use objects instead of arrays. When you use string indexes on array elements the array gets turned into an object and some of the array methods might not work properly afterwards. Why not just use an object from the beginning then.
WARNING !!
If you use named indexes, JavaScript will redefine the array to a standard object.
After that, some array methods and properties will produce incorrect results.
this is taken from https://www.w3schools.com.
Here is an example of how to use it:
// Object = {} instead of array = []
var myObject = {};
myObject['category'] = {1: {subcategories: {1:[1,2], 2: [3,4] }} };
// For example
var anotherObject = {};
anotherObject['category'] = {1: {}, 2: {}};
anotherObject['category'][1] = [1,2];
anotherObject['category'][2] = [3,4];
// Edit: example 3
// ---------------
// result from database JSON format
var resultFromDB = {"category": {"1": {"subcategories": {"1": {"subsubcategories": [1,2]}, "2": {"subsubcategories": [3,4] }}}} };
// example of building new object from input
var myNewObject = {};
var type;
// go through the first level
for(var index in resultFromDB)
{
// in case you needed this is how you would check type of input
type = typeof resultFromDB[index];
if((type === "object") && (type !== null)) // check if its an object
{
// set myNewObject[index] to new object
myNewObject[index] = {};
// go through second level
for(var subIndex in resultFromDB[index])
{
// set myNewObject[index][subIndex] as new object
myNewObject[index][subIndex] = {};
// go through third level
for(var subSubIndex in resultFromDB[index][subIndex])
{
// simply use an '=' to get all from that level
myNewObject[index][subIndex][subSubIndex] = resultFromDB[index][subIndex][subSubIndex];
}
}
}
}
console.log("This is the new object");
console.log(myNewObject);
console.log("\n");
console.log("This is the original object");
console.log(myNewObject);
// If you need to extract in multiple places you could make a function for quick access
function returnObject(incomingObject)
{
var myNewObject = {};
var type;
// ... copy paste here all the above code from example 3 except resultFromDB
return myNewObject;
}
// then just call it from anywhere
var theNewestObject = returnObject(resultFromDB);
Related
Why does changing the value of a property change the value for all similar properties in an array and how do I get it to work right without using the this keyword for 'name'?
let Object = {
'name' : 'Test Object'
}
let Array = []
Array.push(Object)
Array.push(Object)
Array.push(Object)
Array[0]['name'] = 'Changed'
console.log(Array) // expect only the first name to change, but all 3 change...
You aren't changing "similarly named" objects, you are changing the same object.
For non-primitives (basically everything that isn't a string, number, or boolean), they are passed by reference. That means when you add them to something like an array or pass them to a function, you are basically passing their address. If you pass it 3 times, they all point to the same address; there is still only one copy. Change one, and you change them all.
const a = { b: 1 };
const arr = [a, a, a];
// All the same object
console.log(arr[0] === arr[1], arr[1] === arr[2], a === arr[0]);
a.b = 5;
// All 3 changed, because it is the same thing
console.log(arr.map(a => a.b));
function someFunc(obj) { obj.b = 10 };
someFunc(a);
// changed from inside function, same object
console.log(a.b);
If you want to create a handful of objects that all start the same, but then are able to change afterwards, you need to create the objects in a loop:
const template = { name: 'a' };
const arr = [];
for (let i = 0; i < 3; i++) {
arr.push({ ...template }); // or: arr.push(Object.create({}, template))
}
arr[1].name = 'b';
arr[2].name = 'c';
console.log(arr);
Or, even more concisely:
// Creates a new Array with 3 records and then puts a copy of the template in each.
const template = { name: 'a' };
const arr = new Array(3).fill(1).map(() => ({ ...template }));
// or (without needing template variable):
// const arr = new Array(3).fill(1).map(() => ({ name: 'a' }))
arr[1].name = 'b';
arr[2].name = 'c';
console.log(arr);
When you invoke Array.push(Object), you're pushing a reference to the same object into the array 3 times. Push does not make a copy of Object - only 1 Object exists.
If you want 3 identical objects in an array, try something like this:
let vArray = []
for(i = 0; i <= 2; i++) {
//We're going to loop this 3 times, creating 3 different
//objects and pushing each of them into the array
let vObject = {
'name' : 'Test Object'
}
vArray.push(vObject)
}
vArray[0]['name'] = 'Changed'
console.log(vArray) // Only the first one will have been changed.
The answer I was looking for was to change the syntax in my answer to Array.push({...Object}). This creates a 'new' object to be pushed, with only 5 additional characters...
I didn't know 'object spread syntax' essentially did this.
I want to transpose values from 2 objects to 3 objects.In first object I want 1st value from each objects etc.
If 2 objects with 3 values then after transpose it will become 3 objects with two values.
before transpose
data is
obj 0:
0:"17"
1:0.052708692712917476
2:0.05170448850051073
3:0.036428533456315845
obj 1:
0:"16"
1:0.039474102915939856
2:0.04788765943666215
3:0.03651675504080556
After transpose I want following obj
obj 0:
0:0.052708692712917476 //1st value of 17 i.e obj 0
1:0.039474102915939856 //1st value of 16 i.e obj 1
obj 1:
0:0.05170448850051073 //2nd value of 17 i.e obj 0
1:0.04788765943666215 //2nd value of 16 i.e obj 1
obj 2:
0:0.036428533456315845
1:0.03651675504080556
You could transpose by getting the values and skipping the first property of the inner objects.
var data = { 0: { 0: "17", 1: 0.052708692712917476, 2: 0.05170448850051073, 3: 0.036428533456315845 }, 1: { 0: "16", 1: 0.039474102915939856, 2: 0.04788765943666215, 3: 0.03651675504080556 } },
result = Object.values(data).reduce(
(r, a, i) => (Object.values(a).slice(1).forEach((v, j) => (r[j] = r[j] || {})[i] = v), r),
{}
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES5
var data = { 0: { 0: "17", 1: 0.052708692712917476, 2: 0.05170448850051073, 3: 0.036428533456315845 }, 1: { 0: "16", 1: 0.039474102915939856, 2: 0.04788765943666215, 3: 0.03651675504080556 } },
result = {};
Object.keys(data).forEach(function (k, i) {
Object.keys(data[k]).slice(1).forEach(function (l, j) {
result[j] = result[j] || {};
result[j][i] = data[k][l];
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
With only 2 objects and 2 properties?
Really easy, by accessing their properties directly!
var object1 = {
p11: v11
p12: v12,
p13: v13
}
var object2 = {
p21: v21
p22: v22,
p23: v23
}
You can use 2 notations: dot and array. And you are gonna need an additional helper variable so you don't step over property in 1 object before you transfer it to other.
Dot notation:
var helper = null;
helper = object1.v1
object1.v1 = object2.v2;
object2.v2 = helper;
Array-like or brackets notation:
var helper = null;
helper = object1.v1
object1["v1"] = object2.["v2"];
object2.["v2"] = helper;
It's hard to read what exactly transformation you wanna since but this is a basic simple way to let's say exchange properties of 2 objects. You can rinse and repeat this principle for multiple exchanges.
Remember, don't write new value over old one before you put old value in an object somewhere.
Oh, now that you made a proper example in question I see what you need. You need to chunk down 2 big objects of coordinates into smaller chunks each having a property from one. I wouldn't call that transpose, at least not by mathematical definition of it.
You need a function actually to give it 2 objects and it returns an array of small objects (ones with 2 properties). I hope those are object literals because unless you can number the properties by name (you have 1, 2, 3 and so on) in JS there is no way to ensure order of properties in object. Arrays are special objects used for that.
Oke, assuming you posted literals (only in inpropper syntax) let's write a function:
var getCoordinates = function (obA, obB){
var o1 = null;
var o2 = null;
var coordinatesArray = [];
// determine which object under property 0 has bigger value to know order
if (obA[0] < obB[0]) {
o1 = obA;
o2 = obB;
}
else {
o2 = obA;
o1 = obB;
}
// get value pairs assuming both objects have same number of properties
// if not, get as much as you can until one object runs out of coordinates
for (i=1; true; i++;){ // start at 1, 0 is reserved for object order
if (o1.hasOwnProperty(i+"") && o2.hasOwnProperty(i+""){
var coordinatePair = {};
coordinatePair["0"] = o2.[i+""];
coordinatePair["1"] = o1.[i+""];
coordinatesArray.push(coordinatePair);
}
else break;
}
return coordinatesArray;
}
}
Written purely from the head so I might have missed syntax (I am on tablet). But it should demo you the right idea.
update
I have adjusted/corrected the example objects, because they contained an error before.
I have an mapping object that looks like this:
var AtoB = {
"amore" : "love",
"alimenti": "food",
"Bier" : "beer"
};
which allows to map one way i.e. AtoB["love"] yields "amore". I could add an inverse to it manualy i.e.
var BtoA = {
"love": "amore",
"food": "alimenti",
"beer": "Bier"
};
Anyway it troublesome the two objects in sync and I would like to create the BtoA programmatically in Javascript. Is there some sort of function xyz() which yields var BtoA = xyz(AtoB);?
The example above can be extended to include a problem (e.g. if I have too much "beer")
var AtoB = {
"amore" : "love",
"alimenti": "food",
"Bier" : "beer"
"cerveza" : "beer",
"pivo" : "beer",
"birra" : "beer",
"cerveja" : "beer"
};
as this is not a 1-to-1 mapping. In amateuer math terms It is not an inversible function?
To make things even more complicated I have a recipe for desaster.
var makeStuff = {
"agriculture": "food",
"hops" : {
"water": {
"malt": "beer"},
"malt": {
"water": "beer"}},
"water" : {
"hops": {
"malt": "beer"},
"malt": {
"hops": "beer"}},
"malt" : {
"water": {
"hops": "beer"},
"hops": {
"water": "beer"}}
};
inversing this nested javascript object, seems even more challanging for such an xyz() function. Anyway maybe there is such an xyz() function, then I would be glad to accept this as an answer to this question
Very simple. Following is the code to inverse key, value.
var inverse= (function inv(param){
for(var attr in param) {
if(param.hasOwnProperty(attr)) {
if(typeof param[attr]==="string") {
param[param[attr]] = attr;
delete param[attr];
} else if (Object.prototype.toString.call(param[attr]) === "[object Object]") {
param[attr] = inv(param[attr]);
}
}
}
return param;
});
To get the result into other object, initialize it with empty and assign it. Like
var BtoA = {};
BtoA = inverse(AtoB);
And, The JSON:
var AtoB = {
"love": "amore",
"food": "alimenti",
"beer": "Bier",
"beer": "cerveza",
"beer": "pivo",
"beer": "birra",
"beer": "cerveja",
};
has only three attributes because JSON is a dictionary data structure: new key will replace the old one. So the above JSON will actually be like:
{love: "amore", food: "alimenti", beer: "cerveja"}
So, inverting the above given JSON (AtoB) will result in the inversion of only three properties, and final result will be:
{amore: "love", alimenti: "food", cerveja: "beer"}
The answer from Muhammad imran is effective if the purpose/target is a simple inversion (i.e. no nested object structure; no multiple values).
Obviously that is the best result to be achieved, if no further artifice is created, to cover the fact that the key->value relation in objects are:
keys are unique,
values can be muliple.
Looking at the beer example above it is somewhat regretible that the information is lost in the inversion. Therefore this answer should supplement and enrich and provide a way in which the information can be stored. The way to achieve it is using Javascript Arrays within the resulting inverted object, to allow to store the potentially ambigious new values. as for example.
var BeerAtoB = {
"amore" : "love",
"alimenti": "food",
"Bier" : "beer",
"cerveza" : "beer",
"pivo" : "beer",
"birra" : "beer",
"cerveja" : "beer"
};
allowing to translate (de,es,pl/cz,it,pt)"beer" to English would best store
this information in the inverted too
var BeerBtoA = {
"love" : "amore",
"food" : "alimenti",
"beer" : [ "Bier" ,
"cerveza",
"pivo",
"birra",
"cerveja"
]
};
a version in which less information get lost and the multipleness of the original value "beer" is reflected by multipleness of values under the joint, inverted key "beer" now.
To accomplish this I made an enhanced inverting function
function invertObject(obj)
{
var invertedObject = {};
// make a stack and prime it with the obj
var stack = [];
stack.push({"way":[],"obj":obj});
// while stuff on the stack
while (stack.length)
{
var way= stack[0].way;
var obj= stack[0].obj;
for (var prop in obj)
{
if (typeof obj[prop] === 'object')
{
// attributes, which are themselves objects are added to the stack,
// with their way information.
stack.push({"way":way.concat(prop),"obj":obj[prop]});
}
else
{
// always start with adding things to the invertedObject,
var curobj = invertedObject;
var value = newKey = obj[prop];
var curpath = way.concat(prop).concat(obj[prop]);
// for all but the last two path elements the loop below
// will create the inverted path, starting with the value (obj[prop])
// as key, Since values need not be unique (as keys), create each
// such new key-property as an Array, not to loose inverted pathes.
while(curpath.length>2)
{
var pathpart = curpath.pop();
if(!curobj.hasOwnProperty(pathpart))
{
curobj[pathpart]=[];
}
curobj=curobj[pathpart];
}
// the last two curpath Array members represent the last key and the
// new to be added value.
var preLastPart = curpath.pop();
var lastPart = curpath.pop();
// Again the artifice of an Array is used since
// the inverted keys are not unique, hence cases in which
// 1 key has (>1) values.
if(!curobj.hasOwnProperty(preLastPart))
{
curobj[preLastPart]=[];
}
curobj[preLastPart].push(lastPart);
}
}
stack.shift();
}
return invertedObject; function invertObject(obj)
{
var invertedObject = {};
// make a stack and prime it with the obj
var stack = [];
stack.push({"way":[],"obj":obj});
// while stuff on the stack
while (stack.length)
{
var way= stack[0].way;
var obj= stack[0].obj;
for (var prop in obj)
{
if (typeof obj[prop] === 'object')
{
// attributes, which are themselves objects are added to the stack,
// with their way information.
stack.push({"way":way.concat(prop),"obj":obj[prop]});
}
else
{
// always start with adding things to the invertedObject,
var curobj = invertedObject;
var value = newKey = obj[prop];
var curpath = way.concat(prop).concat(obj[prop]);
// for all but the last two path elements the loop below
// will create the inverted path, starting with the value (obj[prop])
// as key, Since values need not be unique (as keys), create each
// such new key-property as an Array, not to loose inverted pathes.
while(curpath.length>2)
{
var pathpart = curpath.pop();
if(!curobj.hasOwnProperty(pathpart))
{
curobj[pathpart]=[];
}
curobj=curobj[pathpart];
}
// the last two curpath Array members represent the last key and the
// new to be added value.
var preLastPart = curpath.pop();
var lastPart = curpath.pop();
// Again the artifice of an Array is used since
// the inverted keys are not unique, hence cases in which
// 1 key has (>1) values.
if(!curobj.hasOwnProperty(preLastPart))
{
curobj[preLastPart]=[];
}
curobj[preLastPart].push(lastPart);
}
}
stack.shift();
}
return invertedObject;
}
}
Indeed since equal values can be found in many places of simple and nested object, the result will be an object in which each value will be an Array for two reasons:
Several original object's keys, can have the same value, and therefore (after inverting) more than one value can exists. An Array can store all those multiple new values, hence all information.
While in an nested object, the uniqueness makes every property either a direct value or a subobject, in the inverted object at a key, we can find not only muliple values, but also that at the very same place there are also further nested objects. (For this reason it is lucky that an Javascript Array, as being an Object, does besides its entry allow also for further properties to be attached to it and hence can serve simultaneously as a storage for the multiple values and as a subkey in the nested structure. Such a double purpose of Arrays in the inverted object structure, is unforunatelly hard to show in JSON notation, as the JSON notation does not allow for Arrays with Object Attributes)
I am trying to pass some data to a function that uses those arguments as identifiers for a multi dimensional array, and then return the value hardcoded to that array. I am not sure what I am doing wrong, but something is breaking.
I can get an alert() to pop before I assign any array values, but it seems to die at that point. Any help is appreciated.
// Get Column A's number
var a1 = Number($('#p-a').attr("numb"));
// Get Column B's number
var b1 = Number($('#p-b').attr("numb"));
// Get status for column A
var a_status = $('#p-a').attr("status");
// Get status for column A
var b_status = $('#p-b').attr("status");
// If same, status="s" else, status="i"
var status = "";
if(a_status == b_status) { status = "s"; }else{ status = "o"; }
// Get the value of the numbers + status
var a = this_function(a1, b1, status, "2");
// Update the status div
$('#status').html(a);
function this_function(a1, a2, s, p)
{
this_array = array();
this_array['1']['1']['1']['1'] = "10";
this_array['1']['1']['1']['2'] = "20";
this_array['1']['2']['1']['1'] = "40";
this_array['1']['2']['1']['2'] = "60";
//
return this_array[a1][a2][s][p];
}
You cannot initialize arrays like that. Every level needs to be initialized individually. And as you don't have numerical keys only, I'd use an object instead:
var this_array = {
'1': {
'1': {
'o': {
'1': "10",
'2': "20"
}
},
'2': {
'o': {
'1': "40",
'2': "60"
}
}
}
};
You'd also have to define what happens if a key does not exist. E.g. currently, if status is 's' then you will get an error.
The if statement can be written shorter using the conditional operator:
var status = (a_status == b_status) ? 's' : 'o';
Update: If you really want to have a numerical array, provided the keys are numerical only, you can create the array like so:
var this_array = [
[], // this_array[0]
[ // this_array[1]
[], // this_array[1][0]
[ // this_array[1][1]
[], // this_array[1][1][0]
[null, 10, 20] // this_array[1][1][1][...]
],
[ // this_array[1][2]
[], // this_array[1][2][0]
[null, 40, 60] // this_array[1][2][1][...]
]
]
];
You see, if you do not start your indices with 0 the structure becomes quite confusing.
Your array notation within this_function is incorrect (barring your having an array function that creates the array in the form you show). Notes:
function this_function(a1, a2, s, p)
{
this_array = array(); // <== There is no `array` function in std. JavaScript
this_array['1']['1']['o']['1'] = "10"; // <== Unless you've created an object/array at this_array['1'] (which you haven't), this line will fail
this_array['1']['1']['o']['2'] = "20";
this_array['1']['2']['o']['1'] = "40";
this_array['1']['2']['o']['2'] = "60";
//
return this_array[a1][a2][s][p];
}
I'm not entirely sure what this_function should do, or I'd offer a replacement function. Some thoughts:
Creating an array, you use [] (or new Array(), but that's just a longer form of the same thing).
You have to create each object/array in an array. So you can't assign to this_array['1']['1']['o']['1'], for instance, until you've created an object/array at this_array, this_array['1'], this_array['1']['1'], and this_array['1']['1']['o'].
Your this_function function will create a new array each time it's called. That seems dramatically inefficient.
JavaScript arrays aren't really arrays, they're just objects with some special features. You may just want objects, given that not all of your keys are numeric. If you really want arrays, though, they mostly start with index 0 rather than 1.
You're quite correct that array indexes are really strings, but they're almost always written as numbers and it's totally fine to do that (leaving off the quotes). Using the quotes (which is, again, technically correct) will tend to confuse people trying to maintain the code. (But if you use objects rather than arrays, it will mostly help.)
First and foremost there is no array() function in Javascript. I don't know if it refers to some other point of your code but arrays are created via the array constructor new Array() or an array literal []
Secondly what you are using is not a real numberical indexed array.
For the assignment part: you have one array/object but the deeply nested objects/arrays are undefined.
Your code dies at: this_array['1']['1']['o']['1'] = "10"; because this_array['1'] is undefined which can't have any property so the chain is broken.
Then there is a problem with types. You convert the attribute to number by Number($('#p-a').attr("numb")); and then you use strings as indexes. This is related to the array/object confusion.
What you need is to create a real array, and use numerical indexes:
// move it outside so you only
// create this beast once
var array = [ // first level
[ // second level
[ // third level
[10, 20] // fourth level
],
[
[40, 60]
]
// , [...]
]
];
function this_function(a1, a2, s, p) {
return array[a1-1][a2-1][s-1][p-1];
}
i'm not well versed in needing to deal with multidimensional arrays, but you need to define all your inner arrays before you can set them to anything. something like this:
var this_array = [];
this_array['1'] = [];
this_array['1']['1'] = [];
this_array['1']['2'] = [];
this_array['1']['1']['o'] = [];
this_array['1']['2']['o'] = [];
this_array['1']['1']['o']['1'] = "10";
this_array['1']['1']['o']['2'] = "20";
this_array['1']['2']['o']['1'] = "40";
this_array['1']['2']['o']['2'] = "60";
i tried to console this result out and everything came up as undefined, but within the array at least and didn't die.
When I create a new JavaScript array, and use an integer as a key, each element of that array up to the integer is created as undefined.
For example:
var test = new Array();
test[2300] = 'Some string';
console.log(test);
will output 2298 undefined's and one 'Some string'.
How should I get JavaScript to use 2300 as a string instead of an integer, or how should I keep it from instantiating 2299 empty indices?
Use an object, as people are saying. However, note that you can not have integer keys. JavaScript will convert the integer to a string. The following outputs 20, not undefined:
var test = {}
test[2300] = 20;
console.log(test["2300"]);
You can just use an object:
var test = {}
test[2300] = 'Some string';
As people say, JavaScript will convert a string of number to integer, so it is not possible to use directly on an associative array, but objects will work for you in similar way I think.
You can create your object:
var object = {};
And add the values as array works:
object[1] = value;
object[2] = value;
This will give you:
{
'1': value,
'2': value
}
After that you can access it like an array in other languages getting the key:
for(key in object)
{
value = object[key] ;
}
I have tested and works.
If the use case is storing data in a collection then ECMAScript 6 provides the Map type.
It's only heavier to initialize.
Here is an example:
const map = new Map();
map.set(1, "One");
map.set(2, "Two");
map.set(3, "Three");
console.log("=== With Map ===");
for (const [key, value] of map) {
console.log(`${key}: ${value} (${typeof(key)})`);
}
console.log("=== With Object ===");
const fakeMap = {
1: "One",
2: "Two",
3: "Three"
};
for (const key in fakeMap) {
console.log(`${key}: ${fakeMap[key]} (${typeof(key)})`);
}
Result:
=== With Map ===
1: One (number)
2: Two (number)
3: Three (number)
=== With Object ===
1: One (string)
2: Two (string)
3: Three (string)
Compiling other answers:
Object
var test = {};
When using a number as a new property's key, the number turns into a string:
test[2300] = 'Some string';
console.log(test['2300']);
// Output: 'Some string'
When accessing the property's value using the same number, the number is turned into a string again:
console.log(test[2300]);
// Output: 'Some string'
When getting the keys from the object, though, they aren't going to be turned back into numbers:
for (var key in test) {
console.log(typeof key);
}
// Output: 'string'
Map
ECMAScript 6 allows the use of the Map object (documentation, a comparison with Object). If your code is meant to be interpreted locally or the ECMAScript 6 compatibility table looks green enough for your purposes, consider using a Map:
var test = new Map();
test.set(2300, 'Some string');
console.log(test.get(2300));
// Output: 'Some string'
No type conversion is performed, for better and for worse:
console.log(test.get('2300'));
// Output: undefined
test.set('2300', 'Very different string');
console.log(test.get(2300));
// Output: 'Some string'
Use an object instead of an array. Arrays in JavaScript are not associative arrays. They are objects with magic associated with any properties whose names look like integers. That magic is not what you want if you're not using them as a traditional array-like structure.
var test = {};
test[2300] = 'some string';
console.log(test);
Try using an Object, not an Array:
var test = new Object(); test[2300] = 'Some string';
Get the value for an associative array property when the property name is an integer:
Starting with an associative array where the property names are integers:
var categories = [
{"1": "Category 1"},
{"2": "Category 2"},
{"3": "Category 3"},
{"4": "Category 4"}
];
Push items to the array:
categories.push({"2300": "Category 2300"});
categories.push({"2301": "Category 2301"});
Loop through the array and do something with the property value.
for (var i = 0; i < categories.length; i++) {
for (var categoryid in categories[i]) {
var category = categories[i][categoryid];
// Log progress to the console
console.log(categoryid + ": " + category);
// ... do something
}
}
Console output should look like this:
1: Category 1
2: Category 2
3: Category 3
4: Category 4
2300: Category 2300
2301: Category 2301
As you can see, you can get around the associative array limitation and have a property name be an integer.
NOTE: The associative array in my example is the JSON content you would have if you serialized a Dictionary<string, string>[] object.
Simple solution if you would rather use an array.
When adding the number just preface it with a letter.
e.g.
let ctr = 3800;
let myArray=[];
myArray["x" + ctr.toString()]="something";
myArray["x" + (ctr+1).toString()]="another thing";
Then just add the "x" in access routines that call the number as an index.
e.g.:
console.log( myArray["x3800"] );
or:
console.log( myArray["x"+ numberOfYourChoice.toString()] );
Use an object - with an integer as the key - rather than an array.
Sometimes I use a prefixes for my keys. For example:
var pre = 'foo',
key = pre + 1234
obj = {};
obj[key] = val;
Now you don't have any problem accessing them.