We're building a dynamic JSON payload according to a simple template format that instructs how many levels our payload should produce, e.g. "level1.level2" > will produce:
{
"level1": [
{
"level2": [
{
"someData": "willGoHere",
},
{
"someOtherData": "willAlsoGoHere"
}
]
}
]
}
Obviously we're working with a different naming structure, e.g: "client.ipcEvent.level3" and in some cases we're testing 4 levels. We're doing something wrong ~ we're able to build our javascript object but unable to use stringify() to create a full result because for some strange reason stringify() against our object only returns the 1st level's data:
{ "level1": [] }
.
I've tried changing the way in which our object is loaded with values but it all comes back to stringify() 'dropping' off array values that don't have accompanying attribute/property values at the same level.
The issue is that your client is an array, but you've put properties on it that aren't array entries (which you can do because arrays are objects):
JSON.stringify only includes the array entries of an array, not its other properties:
const a = [];
a.nonEntryProperty = "foo";
a[0] = "bar";
console.log(JSON.stringify(a)); // ["bar"]
To ensure data is serialized to JSON correctly, include object-like properties in objects, and array entries in arrays:
const structure = {
info: {
nonEntryProperty: "foo"
},
array: ["bar"]
};
console.log(JSON.stringify(structure, null, 4));
OK, solved; we were creating arrays when it should have been objects, and vice-versa; sorry for the vague question but thank you TJ and Sebastian. Based on the specification of "level1.level2" the solution was to create object {} for "level1" and array [] for the last item "level2"...
I have data in a .json file, in the form:
{
"ObjectA": {},
"ObjectB": {},
"ObjectC": {}
}
I want to remove the names (ObjectA, B etc.) so I end up with 'anonymous' objects:
{
{},
{},
{}
}
Delete only deletes properties of an object, so that won't work. What will do the trick?
Might not be the cleanest method, but gets the job done. (I added values so your console log is easier to see that the data is coming across.
var obj = {
ObjectA: {fu:'bar'},
ObjectB: {iheart:'pizza'},
ObjectC: {something:'value'}
};
var obj2 = {};
var i = 0;
for (var key in obj) {
obj2[i] = obj[key];
i++;
}
obj = obj2; // don't really need this - could just use obj2
console.log(obj);
I'm sure this could be cleaned up and written in less code, but you get the idea of at least one way you can do that.
As far as I know, data can only be represent in one form i.e: Key->value. In every case, whether you talk about JSON data, MYSQL data or Object alloc in heap.
For making this easy we have generalised data storing in 2 methods.
Data in Dictionary
Data in Array
Dictionary holds each data with a unique "key". Like you already have in json "ObjectA" is a key. And Array also holds data with a unique key user don't have to specify that key while pushing data into array. we call that key "index".
So technically array is also a dictionary with auto-incremented "key" for each data.
Now, lets get into the point. You want to save your data in json with out any key. It means you have to save data in an ARRAY.
like:
{
objects : { [{}, {}, {} ]}
}
but remember you need to save that array adjacent to any "key". You can't get rid from key->value rule.
I'm trying to build a key/value relationship for an ajax based web app. I've decided to use a pure array-based approach as iterating arrays is faster than objs (or so I'm told).
The base of the idea looks like this:
var keyVals = [
[ "key1", ["value1"] ],
[ "key2", ["value2"] ],
];
However when I iterate the array to delete/set or change a key, the event doesn't run as expected:
For example:
console.log(keyVals);
function delKeyPair(key) {
for (var i = 0; i < keyVals.length; i++) {
if (keyVals[i][0] && keyVals[i][0] === key) {
Array.prototype.splice.call(keyVals, i, 1);
return true
}
}
return false
};
delKeyPair("key1");
console.log(keyVals);
When I first console.log() the array - it shows that "key1 has already been deleted, before the function is called.
here is a fiddle, not quite sure what's going on. Any help is much appreciated.
http://jsfiddle.net/3pfj8927/
key1 has not already been deleted before calling function:
try console.log(keyVals.length);
DEMO
Output:
Length before deleting: 2
Length after deleting: 1
The console runs asynchronously. It also keeps a reference to your object.
Your code is running just fine.
When you look at the object in the console, it shows you the current way it looks, not how it was at the time of the log.
If you replace console.log(keyVals); with console.log(keyVals.slice());, you should see the proper objects, because we copy them as-is.
The key1 has not been deleted. Note you're working on a reference of the given array. If you inspect the Array it will be loaded by the reference. Because you're changing the reference in the delKeyPair function it seems that there never was a key1.
If you copy the array on delete you'll see everything works like expected.
I want to be able to save an array (if possible), so that I can get to an entry within it quickly and easily with a unique identifier, something like:
array structure:
[
1001:{loads of info},
1002:{loads more info}
]
and to get values like:
var info_i_want = array.1001;
I have the 'loads of info' part already in a json object, just need to built this new array?
I ask because at the moment I have to loop through each object in the array to check if its the one I want before I can do anything
If you want you can use numeric keys with an object literal (not the array notation you used above):
var obj = {
1001: { /* data */},
1002: { /* data */}
};
With numeric keys, you must use bracket notation to dereference; i.e:
obj[1001]; // *not* dot reference `obj.1001` which will not work
Hope this helps :)
EDIT
For reference read the Object section of Javascript Garden, specifically Accessing Properties
you can assume like this.
var arr = [
{1001: "loads of info"},
{1002: "loads more info"}
]
var info_i_want = arr[0].1001 // returns loads of info
I am a bit confused at this point on what is an object, what is an array, and what is a JSON. Can someone explain the differences in syntax between the two? and how to add items to each, how to merge each type, and such? I am trying to get this function to take the new information from a JSON object (I think) and merge it with some new information. This information will then be passed to a PHP script to be processed.
Here is the console output:
{"public":{"0":["el29t7","3bmGDy"]}}
{"public":"[object Object][object Object]"}
Here is the JS I am using:
/* Helper function to clean up any current data we have stored */
function insertSerializedData(ids, type) {
// Get anything in the current field
current_data = $('#changes').val();
if (!current_data) {
var data = {};
data[index++] = ids;
var final_data = {};
final_data[type] = data;
$('#changes').val(JSON.stringify(final_data));
} else {
current_data = JSON.parse(current_data);
var data = {};
data[index++] = ids;
// Does the index exist?
if (type in current_data) {
var temp_data = current_data[type];
current_data[type] = temp_data + data;
} else {
current_data[type] = data;
}
//var extra_data = {};
//extra_data[type] = data;
//$.merge(current_data, extra_data);
$('#changes').val(JSON.stringify(current_data));
}
console.log($('#changes').val());
}
The idea is if the key (public, or whatever other ones) doesn't exist yet, then to make it point to an array of arrays. If it does exist though, then that of array of arrays need to be merged with a new array. For instance:
If I have
{"public":{"0":["el29t7","3bmGDy"]}}
and I want to merge it with
["aj19vA", "jO71Ba"]
then final result would be:
{"public":{"0":["el29t7","3bmGDy"], "1":["aj19vA", "jO71Ba"]}}
How can i go about doing this? Thanks
Excellent two-part question. Overall, the second question is non-trivial because of the complexity of the first.
Question 1:
what is an object, what is an array, and what is a JSON. Can someone
explain the differences in syntax between the two?
Question 2:
and how to add items to each,
Question 3:
how to merge each type, and such?
Answer 1:
This is a common stumbling point because, JavaScript is more flexible than one might initially expect. Here is the curve.
In JavaScript everything is an object.
So here is the code for each:
//What is an object?
var obj = { };
var obj2 = { member:"value", myFunction:function(){} }
Above is an empty object. Then another object with a variable and a function.
They are called object-literals.
//What is an array
var array1 = [ ] ;
var array2 = [0,1,2,3,4];
Above is an empty array. Then another array with five Integers.
Here is the curve that causes confusion.
//Get elements from each of the prior examples.
var x = obj2["member"];
var y = array2[1];
What??? Both Object and Array are accessing values with a bracket?
This is because both are objects. This turns out to be a nice flexibility for writing advanced code. Arrays are objects.
//What is JSON?
JSON stands for JavaScript Object Notiation. As you might have guessed. Everything is an object... It is also an { }; But it is different because - it is used to transfer data to - and - from JavaScript, not actually used (commonly) in JavaScript. It is a file transfer format.
var JSONObject = {"member":"value"};
The only difference to the prior example is quotes. Essentially we are wrapping the object literal as a string so that it can be transferred to a server, or back, and it can be reinterpreted, very easily. Better than XML - because it does not have to be custom-parsed. Just call, stringify() or ParseJSON(). Google it. The point is... JSON can be converted into an object-literal JS object, and JS object-literals can be converted into JSON, for transfer to a server or a CouchDB database, for example.
Sorry for the tangent.
Answer 2:
How to add an item to each? Here is where the curve stops being a nuisance, and starts being awesome! Because everything is an object, it is all just about the same.
//Add to an object
var obj {member1:"stringvalue"}
obj.member2 = "addme"; //That is it!
//Add to an array
var array1 [1,2,3,4,5];
array1[0] = "addme";
array[6] = null;
//We shouldn't mix strings, integers, and nulls in arrays, but this isn't a best-practice tutorial.
Remember the JS object syntax and you may start to see a whole new flexible world of objects open up. But it may take a bit.
Answer 3: Ah, yeah... how to merge.
There are seriously (very many) ways to merge two arrays. It depends on exactly what you need. Sorted, Duplicated, Concatenated... there are a few.
Here is the answer!
UPDATE: How to make a beautiful multiple dimensional array.
//Multiple Dimension Array
var array1 = [1,2,3];
var array2 = [3,4];
var arraysinArray = [array1,array2]; //That is it!
Here is the curve again, this could be in an object:
var obj{
array1:[1,2,3],
array2:[3,4]
}
JavaScript is powerful stuff, stick with it; it gets good. : )
Hope that helps,
All the best!
Nash
In this case, think of a JavaScript's object literal {} as being like PHP's associative array.
Given that, an "array of arrays" actually looks like this (using your above desired output):
{public: [["el29t7","3bmGDy"], ["aj19vA", "jO71Ba"]]}
So here we have an object literal with a single property named "public" whose value is a 2-dimensional array.
If we assign the above to a variable we can then push another array onto "public" like this:
var current_data = {public: [["el29t7","3bmGDy"], ["aj19vA", "jO71Ba"]]};
// Using direct property access
current_data.public.push(["t9t9t9", "r4r4r4"]);
// Or using bracket notation
current_data["public"].push(["w2w2w2", "e0e0e0"]);
current_data's value is now:
{public: [
["el29t7","3bmGDy"],
["aj19vA", "jO71Ba"],
["t9t9t9", "r4r4r4"],
["w2w2w2", "e0e0e0"]
]}
So now "public" is an array whose length is 4.
current_data.public[0]; // ["el29t7","3bmGDy"]
current_data.public[1]; // ["aj19vA", "jO71Ba"]
current_data.public[2]; // ["t9t9t9", "r4r4r4"]
current_data.public[3]; // ["w2w2w2", "e0e0e0"]
MDN has very good documentation on Array for insight on other functions you might need.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array
First is an object, that contains array, second is an array.
DEMO showing display output http://jsfiddle.net/GjQCV/
var object={"public":{"0":["el29t7","3bmGDy"]}};
var arr=["aj19vA", "jO71Ba"] ;
/* use object notation to add new property and value which is the array*/
object.public[1]=arr;
It'd be much more natural if {"0": ...} were a true array rather than an object, but anyway:
function maxKey(b) {
var max;
for( var key in b )
var max = key;
return max;
}
function merge(a,b) {
for( var key in a ) {
b[key] = b[key] ? (b[key][maxKey(b)+1]=a[key], b[key]) : a[key];
}
return b;
}
Note that this assumes you would insert at the next integer index
Arrays are a particular kind of Javascript object
JSON is a way of representing Javascript objects (and as such can represent arrays and more)
Objects are much more general, and can be simple objects that can be represented as JSON, or can contain functions and prototypes.
So, this is not an array of arrays (you would access items using JSON notation like myobj["0"]):
{"0":["el29t7","3bmGDy"], "1":["aj19vA", "jO71Ba"]}
This is an array of arrays, which means you can use the push method to add an item, and access items using array notation like myobj[0]:
[ ["el29t7","3bmGDy"], ["aj19vA", "jO71Ba"] ]
It seems like the structure you want is something like this:
var myobj = { "public": [ ["key", "value"], ["key", "value"] ] }
Then if you want to add/merge new items, you'd write this:
if (myobj["public"] != null) {
myobj["public"].push(["newkey", "newval"]);
} else {
myobj["public"] = ["newkey", "newval"];
}