Using an integer as a key in an associative array in JavaScript - javascript

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.

Related

Grabbing names of object of out a JSON object in javascript and storing it in an String Array

So the issues that I am currently having is a string manipulation logic issue. My goal is to store the names of JSON objects in a string array. So it will be easier to access the data later on. But the current issue that I am running into is that the output is nothing that I want or understand of how it is getting it. Currently I am looking for the quotes between the object names and returning it to a string using str.substring, and storing it in an index of newArr. The output equals in 4th code snippet. I have also tried putting an underscore before and after the object name in the JSON object, then searching for the underscore. From my testing this will only work with the first name, which will return "foo" in index 0, while the rest of the indexes equal to '"_'. I know there is something wrong with my logic in the function, but I can not pinpoint what it is. Any help would be appreciated
This is the function that is being ran.
exports.jsonObjectToArray = function (objectToTurn){
var oldArr = JSON.stringify(objectToTurn).split(","),
firstIndex,
secondIndex,
newArr = [];
for(let i = 0; i < oldArr.length; i ++){
firstIndex = oldArr[i].indexOf("\"");
secondIndex = oldArr[i].indexOf(firstIndex, "\"");
newArr[i] = oldArr[i].substring(firstIndex, secondIndex);
}
return newArr;
}
When the function is ran oldArr will equal to this value.
[ '{"foo":"',
'"bar":"0"',
'"Mar":"0"',
'"Car":"0"}'
]
And my goal is to return this. Which will be stored in newArr.
[
"foo",
"bar",
"Mar",
"Car"
]
But after the function runs this is what I get returned.
[
'{"',
'bar":"0',
'Mar":"0',
'Car":"0'
]
To get the keys from an object, simply use Object.keys().
Quick example:
var obj = {
foo: '1',
bar: '2',
car: '3'
};
console.log(Object.keys(obj)); // ==> (3) ["foo", "bar", "car"]
let arr = [ '{"foo":"',
'"bar":"0"',
'"Mar":"0"',
'"Car":"0"}'
]
let arr1 = arr.map(el => el.split('"')[1])

How to create and push values into an 3 dimensional array

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);

creating an array, convert it to json and pass it to php

I want to fill an array dynamically with javascript, then convert it to a json string and pass it to php to deal with it.
The problem:
When I define the array like -code 1- the output is as expected:
var feld = {
"key1" : "1",
"key2" : "2",
"key3" : "3"
};
for (key in feld) { console.log (key + "= " + feld[key]); }
var jsonString = JSON.stringify(feld);
console.log(jsonString);
OUTPUT:
key1= 1
key2= 2
key3= 3
{"key1":"1","key2":"2","key3":"3"}
If I define the array like -code 2-
var feld = new Array ();
feld["key1"]="1";
feld["key2"]="2";
feld["key3"]="3";
for (key in feld) { console.log (key + "= " + feld[key]); }
var jsonString = JSON.stringify(feld);
console.log(jsonString);
OUTPUT:
key1= 1
key2= 2
key3= 3
[]
which means, that with code -2- there is nothing to pass to php.
what's wrong ?
"-code 1-" is not an array, it's a non-array object. "-code 2-" is an array, but being used as a non-array object. (And the reason you don't see your non-array properties when you stringify it is that since it's an array, JSON.stringify only serializes the array entries, not the non-array properties.)
What's wrong is that if you want an array, you need to create an array:
var feld = ["1", "2", "3"];
But it sounds like you don't want an array, you really do want an object, like in your first example. If you convert that to JSON and send it to your server, use json_decode to decode it into a PHP object where you can access the key1, key2, and key3 properties to get their values.
You are confusing arrays in js with arrays in php. If in php you can define literal keys for an array like this:
<?php
$a = array( 'key1' => 1);
$a['key1] === 1
in js that is the equivalent of an object rather than an array.
Js is more mathematichal , if you like, with the concept of array,
a = [2, 4, 6];
it is just a list of values/ objects each given by a numeric index.
a[1] === 4
In JavaScript you can attach properties to an array, which will not be member of this array. For example:
let array = new Array(); // Creates empty array: []
array[0] = 123; // Inserts a member to array
console.log(array) // Will output: [123]
array["abc"] = 789 // Attaches a property to array
console.log(array) // Will output: [123], no members were added to array
console.log(array.abc) // Will output: 789
This is possible because Array also acts as an object, so it has members (indexed) and also properties (having keys).
Arrays do not have keys (key0,key2,key3,...), only indexes (0,1,2,...). You probably want either a map or an array. The map is created by code you have attached to the question (first section), the array can be created as following:
var feld = new Array ();
feld[0]="1";
feld[1]="2";
feld[2]="3";
var jsonString = JSON.stringify(feld);
console.log(jsonString);
You have to objectify your array:
...
feld = Object.assign({}, feld);
var jsonString = JSON.stringify(feld);
...

Forcing javascript key integer fills array with null

I am creating an array in Javascript where the product id is used for the key. As the key is numeric, the array is filling gaps with null.
So for example, if I had only two products and their ids were 5 and 7, I would do something like:
var arr = []
arr[5] = 'my first product';
arr[7] = 'my second product';
This array is then passed to a PHP script but upon printing the array, I get the following;
Array (
[0] = null
[1] = null
[2] = null
[3] = null
[4] = null
[5] = My first product
[6] = null
[7] = My second product
)
my ID numbers are actually 6 digits long, so when looping over the array, there are 100,000 iterations, even if I actually only have two products.
How can I create the array so the null values are not entered? I thought of making the key a string instead but as the array is build dynamically, I am not sure how to do that.
var arr = [];
for(var i=0; i<products.length; i++)
{
array[products[i].id] = products[i].name;
}
Thanks
For iterating the array, you could use Array#forEach, which skips sparse items.
var array = [];
array[5] = 'my first product';
array[7] = 'my second product';
array.forEach(function (a, i) {
console.log(i, a);
});
For better organisation, you could use an object, with direct access with the given id.
{
5: 'my first product',
7: 'my second product'
}
Forcing javascript key integer fills array with null
You are declaring an empty array and then setting values into 6th and 8th element in the array. That leaves the values of other elements as null.
If you don't intend to push items into array, i.e. use objects. Something like,
var obj = {};
obj[5] = "my first product";
obj[7] = "my second product";
This means the object created is:
obj = {"5":"my first product","7":"my second product"}
var arr = []
arr[5] = 'my first product';
arr[7] = 'my second product';
let result = arr.filter(ar => ar != null);
console.log(result);

Add item to array by key in JavaScript

I need to group item having same name property and increase their number. I try to assign to new array and check existed item by key. It works fine when I use this solution in PHP, but in JavaScript it doesn't.
I have searched some similar questions, but I don't know why it doesn't work.
var orgArr = [
{name: 'abc', number: 3},
{name: 'xyz', number: 2},
{name: 'abc', number: 5}
];
var result = []; //work if result = {};
for (var i = 0; i < orgArr.length; i++) {
if (!result[orgArr[i].name]) {
result[orgArr[i].name] = orgArr[i]; //assign new
} else {
result[orgArr[i].name].number += orgArr[i].number; //increase number if name exist in result array
}
}
alert(JSON.stringify(result)); //expect array 2 item but it's empty array
console.log(result); //Will have result 2 item when I view console window
var orgArr = [
{name: 'abc', number: 3},
{name: 'xyz', number: 2},
{name: 'abc', number: 5}
];
var result = []; //work if result = {};
var tempArray = []; // used to store unique name to prevent complex loop
orgArr.forEach(function(item){
if($.inArray(item.name, tempArray)< 0){// unique name
result.push(item);
tempArray.push(item.name);
}
else{
var indexNew = $.inArray(item.name, tempArray);
result[indexNew].number += item.number;
}
});
alert(JSON.stringify(result)); //expect array 2 item but it's empty array
console.log(result); //Will have result 2 item when I view console window
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
E/ My previous answer was incorrect.
Well.. yes...
[] designates an array. An array holds everything by integer values. You're trying to feed it a string value (orgArr[x].name) and since its just an array, it discards it as a bad call.
{} is an object. Objects can have string indexes.
var result = []; //work if result = {};
Why can't result be {}?
if you want it to work, make result = {} not []
an array is not a key value store. It still will take key values, and will store them on the array object. But when stringify encounters your array, it determines it is an array and then trys to iterate the array, and your array appears empty. so you get nothing in your output.
You get empty array it's because by default JSON.stringify failed to convert your array to json string.
By default JSON.stringify converts int-based index array to json string but you are using orgArr[i].name which is a string as array index that the cause alert() show empty array.
Can you explain why would you want to convert json array to an array with string index. It's always better to use json array if you want a string as key/index.
For more information about JSON.stringify

Categories

Resources