Serializing a Javascript object with contained arrays to json? - javascript

I have a javascript object that contains a few objects that contain associative arrays. I've been trying to use the json2.js library's stringify function but the output doesn't contain the arrays held in the contained object members.
In my code I start with something like this
obj = {"arr1" : [], "arr2" : [], "arr3" : []};
then I add to it with loops that fill each of the contained arrays
obj[arr*].push[arritem*];
obj[arr*][arritem*] = something;
The arr* and arritem* I put in just to represent the variable I am putting in for the loops.
I try Json.stringify(obj) but the string I get back is
'{"arr1" : [0], "arr2" : [0], "arr3" : [0]}'
I would like to see the ouput as
'{"arr1" : [ "arritem1" : something, "arritem2" : something2], "arr2" : [ "arritem1" : something, "arritem2" : something2], "arr3" : [ "arritem1" : something, "arritem2" : something2]}'
is there a better library for this or is there something I have to do before strinfying?

var obj = {"arr1" : [], "arr2" : [], "arr3" : []};
console.log(JSON.stringify(obj));
Works for me.
Filling the arrays works too.
Update
You imply that you are trying to add elements with non-numeric keys to arrays.
This is not valid. In particular, your desired output is not valid JSON. Arrays have only numeric keys, and they are not included in the JSON itself as they are implicitly, sequentially defined.
Arrays are a special type of Object, which handles numeric indexes for you.
var arr = []; // Create array.
arr.push(1); // There is now one element, with index 0 and value 1.
arr["txt"] = 2; // You tried to create a new element,
// but didn't use .push and gave a non-numeric key.
// This broke your array.
console.log(JSON.stringify(arr));
// Output: [1]
Live demo.
Long story short... don't do this. If you want an "associative array", stick with basic objects:
var obj = {}; // Create object.
obj[0] = 1; // There is now one element, with key "0" and value 1.
obj["txt"] = 2; // There is now a second element, with key "txt" and value 2.
console.log(JSON.stringify(arr));
// Output: {"0":1,"txt":2}
Live demo.

obj.toSource()
this will convert your array to source string.

Related

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

How do I add key:value pair in an order in javascript

I need to add key:value into an object.
var a = {}
a['first'] = [a,bunch,of,stuff]
a['eight'] = [another,bunch,of,stuff]
a['two'] = [more,stuff]
but now variable 'a' contains
{eight: [a,bunch,of,stuff],first: [another,bunch,of,stuff],two: [more,stuff]}
while what I wanted was
{first: [another,bunch,of,stuff], eight: [a,bunch,of,stuff],two:[more,stuff]}
I'm guessing the order is based on the alphabetical order of the keys. This is a problem, because I want to display the data into hbs using {#each model as |key value|} in the same order as I wanted it.
in most languages lists have order where objects and sets do not. objects are key value and have no order.
in js arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed. Since an array's length can change at any time, and data can be stored at non-contiguous locations in the array, JavaScript arrays are not guaranteed to be dense; this depends on how the programmer chooses to use them. In general, these are convenient characteristics; but if these features are not desirable for your particular use, you might consider using typed arrays
this basically means you can place data anywhere in array, and it will be in order in the array
var idx = [];
idx[0] = 'hello';
idx[999] = 'world';
so what i believe you're looking for is
var listOfThings = [];
listOfThings.push({ 'first': [ 'things' ] })
listOfThings.push({ 'eight': [ 'stuff' ] })
listOfThings.push({ 'two': [ 'more'. 'things' ] })
then you can loop over accessing the key and value for each object.
Example you have an object, which is already have 2 key pairs, a1 & b2. Then you would like to add k3, you can use this method :
let objData = [{"a1":10,"b2":20},{"b2":11,"a1":23}]
Object.keys(objData).map(
function (object) {
// add k3
objData[object]["k3"] = "foo"
})
Then if you want to sort the keys alphabetically, use this method :
function orderKeyAlfAsc(obj) {
let data = []
for (var i in obj)
data.push(Object.keys(obj[i]).sort().reduce((r, k) => (r[k] = obj[i][k], r), {}))
return data
}
let orderedData = orderKeyAlfAsc(objData)

js array to json but some value disappear

window.onload = function() {
var arr = new Array;
var jsonObj = {
"123": "234"
};
arr['v'] = "234";
arr[0] = jsonObj;
arr[1] = jsonObj;
console.log(JSON.stringify(arr));
}
The above code result is :
[{"123":"234"},{"123":"234"}]
I don't know why the arr['v'] disappeared?
Object and Array are not parsed to JSON the same way.
an Array will only include the numeric keys, and an Object will include all of its keys:
var Arr = [], Obj ={};
Arr[0] = Obj[0] = 'a';
Arr[1] = Obj[2] = 'b';
Arr['key'] = Obj['key'] = 'c';
console.log(JSON.stringify(Arr));
console.log(JSON.stringify(Obj));
so in your case, you could simply use an Onject instead of an array:
var arr = new Object;
var jsonObj = {"123":"234"};
arr['v'] = "234";
arr[0] = jsonObj;
arr[1] = jsonObj;
console.log(JSON.stringify(arr));
Actually, JSON.stringify will ignore non-numeric keys in Array during the Array JSON serialization. From the latest ECMA Spec, in section "24.3.2.4 Runtime Semantics: SerializeJSONArray ( value )", we know JSON.stringify only utilizes length of Array and related numeric keys to do the serialization, and Array length will not be affected by its non-numeric keys. So it is now clear why 'v' (non-numeric keys) disappear in your final result.
You can't use a string as an array index, unless it is a string representation of an integer.
Therefore, arr['v'] has no meaning.
This stackoverflow question goes into more detail, but the relevant part:
Yes, technically array-indexes are strings, but as Flanagan elegantly
put it in his 'Definitive guide':
"It is helpful to clearly distinguish an array index from an object
property name. All indexes are property names, but only property names
that are integers between 0 and 232-1 are indexes."
In JavaScript, basically two types of array, Standard array and associative array. Standard array is defined by [], so 0 based type indexes. And in associative array is defined by {}, in this case you can define string as keys. So in your code you are using both is single array, that's not acceptable. So define the another array if you want strings keys.

Named objects and collection of them

not sure how to ask tbh :)
I'm used of PHP's associative arrays so much that I struggle to understand how to create an "named array" of objects.
Example:
I have two arrays, two ints and one boolean. This represents one of my entities. I have multiple entities on which I'm doing some work.
In PHP I would write:
$entitites[$entitity_id]['items'][] = $item;
$entitites[$entitity_id]['items_status'][] = $item_status;
$entitites[$entitity_id]['items_count']++;
and so on..
How do I do this with objects in JS?
var entities = {items:[], items_status: [], items_count: 0};
entities[entity_id].items.push(item)
How does one name his object for later access (via name or in my case, entity_id?)
This code doesnt work for me to this extend that my webpage goes blank without any errors produced :S
I also tried this:
var entities = {};
var entity = {items:[], items_status: [], items_count: 0};
but then I dont know how to always add values to already existing object in entities object and how to call that exact object via name eg. entity_id.
Halp :(
Keep entities as an object. Then you can just go ahead and add each entity_id as a key and an object which has all the details of that entity as the value.
var entities = {};
entities["1234"] = {
"items" : [],
"items_status" : [],
"items_count" : 0
};
There are 2 types involved here: Objects & Arrays.
Arrays are simple and you're probably familiar with them from any other language:
var myArray = []; // this is an empty array
myArray[0] = 1;
myArray[1] = 2;
myArray[2] = 3;
// you could also use "var myArray = [1, 2, 3];" instead
alert(myArray[1]); // alerts the value 2
Note: arrays are actually objects, and can have non-index properties as well
You can also use various array functions such as .push(), .pop(), .shift() and so on to mutate the array instead.
Objects share the square brackets notation, but the purpose is different:
var myObject = {}; // this is an empty object
myObject[0] = 1;
myObject[1] = 2;
myObject[2] = 3;
alert(myObject[1]); // alerts the value 2
// but also...
myObject['prop'] = 4;
alert(myObject['prop']); // alerts the value 4
// and
myObject.prop2 = 5;
alert(myObject.prop2); // alerts the value 5
// and lastly
alert(myObject.prop); // alerts the value 4
So while arrays are accessed by index, objects are accessed by property names.
As for your entities, it looks like an array of objects. Lets see how we can do that:
function Entity() {
this.items = [];
this.items_status = [];
this.items_count = 0;
}
var entitites = [];
entities.push(new Entity());
entities[0].items = [1, 2, 3];
entities[0].items_status = ['good', 'good', 'poor'];
entities[0].items_count = 3;
Or you can wrap insertion in a more elegant function:
Entity.prototype.insert(item, status) {
this.items.push(item);
this.items_status.push(status);
this.items_count++;
}
entities[0].insert(4, 'excellent!');
If you want to keep control of the indexes in your JS array you can do so by not using .push() :
var entities = [];
entities[5] = {items:[], items_status:[], items_count:0};
Just replace 5 by your integer entity_id variable, and there you go.
You can use a regular javascript object to create the associative array you're looking for.
Actually it's PHP's implementation that's abit off but all they do is call it different (associative array) to most other language that simply refer to it as an object or hash.
You can use numeric keys in JS and still access them with the [] square brackets.
It works like this:
var my_obj = {};
my_obj[5] = 'any value';
console.log(my_obj); // {5: 'any value'}
JS will not add any redundant undefined to missing indexes either so when looping over the collection you won't loop over undefined.
Also, I can access the object by using the key as a string or as number so you won't have to check if the key is the right type. Taken from the above example:
console.log(my_obj['5']); // 'any value'
console.log(my_obj[5]); // 'any value'
JS Objects are the equivelant of PHP assoc arrays except JS objects are much more flexible than PHP's associative arrays.
The only downside to this is that you can't have duplicate keys.
No two keys may exist that share the same name, in an array if you .push(an_item) it will create a new index making even a duplicate data entry unique but when overwriting a key with a new value only the last value will persist, mind that :)

Javascript defining array. "arrayception"

I am trying to create a list of "items" in a canvas game. For example, an array named list. Each element must contain the information about each item. First element will contain something different. I will remove first one with 'shift()' command. Like :
list.shift();
list[0]['name']
list[0]['id']
list[0]['x']
list[0]['y']
list[1]['name']
list[1]['id']
list[1]['x']
list[1]['y']
but i don't know how to define something like this. normally i define arrays like
{"name" : xx, "id" : 5 ... }
but this works like :
list['name']
list['id']
use:
var list = [];
list[0] = {name: 'xx', id: 0, /*etc*/};
list[1] = {name: 'yy', id: 1, /*etc*/};
it creates an array of objects. You can use it like this:
var first = list.shift();
first.name; //=> xx
//or
var first = list[0];
first.name; //=> xx
Note: using {...} (Object literal) creates an Object, not an Array. An array can be created using an Array literal: [...]. Although an object is sometimes said to be an Associative Array, it is not an Array object, so things like {...}.shift() will not work for Objects.
There are no associative arrays in javascript.
so for instance , when you do
var _array = []
_array["field1"] ="value";
you are actually adding a property to the _array object .
_array.field1 = value <=> _array["field1"] ="value";
so if you want to create a collection of objects , do
var collection =[];
var myObject = {"field1":"value1"};
collection.push(myObject);

Categories

Resources