Despite much googling and hair-pulling, I can't for the life of me articulate the difference between json, objects, and arrays (in javascript). Below is how I've been using 2-dimensional data containers (afraid to use the words "array," "object," or "json" here). Please tell me what these two examples are?
//first example:
[
{"record_id":1,"name":"Frank"},
{"record_id":2,"name":"Sally"}
]
//second example:
{
"countries":
[
{"id":1,"name":"Canada"},
{"id":2,"name":"Mexico"}
],
"states":
[
"id":1,"name":"Maine"},
{"id":2,"name":"Alaska"}
]
}
JSON is a representation of the data structure, it's not an object or an array.
[1,2,3]
is an array.
{"foo":"bar"}
is an object.
In your example,
[
{"record_id":1,"name":"Frank"},
{"record_id":2,"name":"Sally"}
]
Is an array of objects.
{
"countries":
[
{"id":1,"name":"Canada"},
{"id":2,"name":"Mexico"}
],
"states":
[
{"id":1,"name":"Maine"},
{"id":2,"name":"Alaska"}
]
}
Is an object containing other arrays and objects inside of it.
JSON is JavaScript Object Notation. This is simply a way of writing down JavaScript data types. It is not a data type in-and-of-itself.
See below for some examples of JavaScript data types, and the literal notation of creating them.
JSON can be used to send data from the server to the browser, for example, because it is easy for JavaScript to parse into a normal JavaScript data structure.
In your example, you are using lists of objects, and objects of objects.
This is a list of 3 empty objects.
[{}, {}, {}]
This is a list of three simple records:
var mylist = [
{name: 'John', age: 24},
{name: 'Bill', age: 42},
{name: 'Jill', age: 18},
]
You can access it like this:
mylist[1].name
>>> 'Bill'
mylist[2].age
>>> 18
JavaScript has several data types:
Number
1
100
-2000
123.45
String
"Hi John"
"Message:\nGo Forth"
Boolean
true
false
Array
[1,2,3]
[]
["a", "b", 123]
["a", "b", 123, [3,4,5]]
Object
{}
{a: 10}
{mylist: [1,2,3], yourlist: [4,5,6]}
{myself: {name: 'me', age: 10}, yourself: {name: 'you', age: 20}}
You use { braces } to declare an object literal.
You use [ square brackets ] to declare an array literal.
Objects are collections of key name value pairs.
Here's an example of an array of strings:
var a = [ "one", "two", "three" ];
Here's an example of a simple object that represents a person:
var personObject = {
name: 'Joe',
age: 25,
hometown: 'New York'
};
JSON is a textual data interchange format. As its name ("JavaScript Object Notation") suggests, it originates from JS; meaning that JSON is actually syntactically valid JavaScript. In other words, you can paste a JSON string directly into your JS code.
Arrays are special Objects. They can be constructed by [].
Objects can be constructed via {}.
So what you have in your example is two JSON strings, one representing an Array of objects, the second one representing an Object whose properties are themselves Arrays of Objects.
Well i believe objects can have methods and properties while arrays cant. JSON can be passed to the server while array cant be, unless you pass it as a string by POST
Related
I've already tried to find a solution on stack, but I didn't found a possible reply, so I decided to open a topic to ask:
Let's say we have 2 arrays: one containing "keys" and another one containing "values"
Example:
keys = [CO2, Blood, General, AnotherKey, ... ]
values = [[2,5,4,6],[4,5,6],[1,3,34.5,43.4],[... [
I have to create a Json with a specific structure like:
[{
name: 'CO2',
data: [2,5,4,6]
}, {
name: 'Blood',
data: [4,5,6]
}, {
name: 'General',
data: [1,3,34.5,43.4]
}, {
...
},
}]
I've tried to make some test bymyself, like concatenate strings and then encode it as json, but I don't think is the correct path to follow and a good implementation of it ... I've also take a look on JSON.PARSE, JSON.stringify, but I never arrived at good solution so... I am asking if someone know the correct way to implements it!
EDIT:
In reality, i didn't find a solution since "name" and "data" are no strings but object
Here's one way to get your desired output:
keys = ["CO2", "Blood", "General", "AnotherKey"]
values = [[2,5,4,6],[4,5,6],[1,3,34.5,43.4],[0] ]
const output = keys.map((x, i) => {
return {"name": x, "data": values[i]}
})
console.log(output)
However, since you're literally constructing key/value pairs, you should consider whether an object might be a better data format to output:
keys = ["CO2", "Blood", "General", "AnotherKey"]
values = [[2,5,4,6],[4,5,6],[1,3,34.5,43.4],[0] ]
const output = {}
for (let i=0; i<keys.length; i++) {
output[keys[i]] = values[i]
}
console.log(output)
With this data structure you can easily get the data for any keyword (e.g. output.CO2). With your array structure you would need to iterate over the array every time you wanted to find something in it.
(Note: The reason you weren't getting anywhere useful by searching for JSON methods is that nothing in your question has anything to do with JSON; you're just trying to transform some data from one format to another. JSON is a string representation of a data object.)
I have a unique problem that I am trying to solve with some complex javascript code. For your information I am using MongoDB, NodeJS, ExpressJS, and VueJS as my technology stack.
I am writing an application that makes api calls to an outside partner of mine that is returning a huge xml based data file. (Unfortunately they are incapable of sending JSON data). After I receive the data from them, I run it through the parseString command of the xml2js library. But the way that it sends the code back is really really strange. From the outside it looks fine, it's an array of objects: [ {object1},{object2},....{objectN} ]. but when you look at the individual objects, it formats the data strangely:
object1 = {
key1: [ 'string' ],
key2: [ '01234657' ],
key3: [ 'email#email.com' ],
key4: [{
key5: [ '8372655573' ],
key6: [ '25.00' ],
key7: [ 'description of item purchased' ]
}],
key8: [ 'otherData' ],
// .......and so on until
NthKey: [ 'dataType' ]
}
I anticipated that the majority of the data I was going to receive was going to consist of single key to single data value pairs, with a few exceptions. But for every single key of the returned object from parseString they assign the value to an array as a string, no matter what. And for the times that a key has a bunch of different data types entered into it (such as with key4 in the example above), I have to dig down into not only an array, but also a nested object inside that array, and into the individual keys that are associated with my data.....
I find that really strange and difficult to work with because now I have to create a bunch of loops that go through and create basically a carbon copy of object 1 except that it looks like this:
object1CarbonCopy = {
key1: String,
key2: Number,
key3: email,
key4: {
key5: Number,
key6: Number,
key7: String
},
key8: String
// and so on until........
NthKey: 'dataType'
}
Do any of you have advice on code that could accomplish this? or if there are settings/options that I can pass into xml2js to change how it spits out the data? Any advice at all would be very appreciated.
So I learned a valuable lesson today, sometimes you need to read through the docs multiple times because you miss things. It turns out that there is an option that turns off that automatic array inserting junk:
parser = new xml2js.Parser( {explicitArray: false} );
If you are viewing this question and don't know what the problem is, pass {explicitArray: false} as a parameter to your Parser constructor
This is a follow up to a previous question I asked:
Sort JSON response by key value
So I know that objects cannot be sorted using the .sort method and if I push each object into an array, I can sort it the way I want.
Why does .sort not work on this:
{ A:{...}, B:{...}, C:{...} }
but works on this:
[ {...}, {...}, {...} ]
It's still accessing and working with object properties in both examples, right?
Here's some code:
var query = {
"736":{
ns: 42,
pageid: 12,
lang: "en",
index: 3
},
"421":{
ns: 12,
pageid: 36,
lang: "en",
index: 4
},
"102":{
ns: 2,
pageid: 19,
lang: "en",
index: 1
}
};
var queryArr = [{ns: 42, pageid: 12, lang: "en", index: 3}, {ns: 12, pageid: 36, lang: "en", index: 4}, {ns: 2, pageid: 19, lang: "en", index: 1}];
query is an object with multiple objects in it, and queryArr is an arry with multiple objects in it. If I wanted to sort query by its index key's value, I'd have to convert it to an arry first, and then run .sort on that array, correct?
What I want to know is why. What prevents query from being sorted, but allows the objects inside queryArr to be sorted? They're both still objects right? The only difference is the outer body is an object in the first, and an array in the second - but it's still working with objects when sorting.
My sort function still referneces the index using the object property accessor:
queryArr.sort(function(i,j){
return j.index - i.index;
});
Array object is object where the positive integer keys are used:
a = [, 1]
a[.1] = .1
a[-1] = -1
console.log( a )
console.log( { ...a } )
If the order of the properties can't be guaranteed, then for example array object [0, 1] can be stored as { "0": 0, "1": 1 } or { "1": 1, "0": 0 }.
Most array looping constructs will look for the "0" property before the "1" property, so the property order doesn't really matter.
Sorting array doesn't change it's properties order, but swaps the values associated with the properties.
Arrays are a special way of sequentially storing data. In the earliest implementations, this would be done by actually storing the array objects sequentially in memory. And resorting would actually physically move the objects in memory. So in your example where you have indices 102, 421, and 736. If you translated this to an array, you would actually have an array of length 737. 0 to 101 would be undefined, then you would have your object at 102. 103 to 420 would be undefined, then object 421. Et cetera.
Good to note that in your example when you translated your object into an array, you lost your keys (102, 421, 736). They simply became (0,1,2). In your example maybe this was okay, but if you had an object with properties like width, height, length, having these replaced with simple array indices like 0,1,2 would be a pretty significant loss of information.
Objects don't work the same way at all. They are not designed to store data sequentially, but hierarchically. So you can have a key 102 that points to an object, but you don't have to have keys 0-101. And key 102 doesn't designate the "order" of the item. It's just a name, and it could just as easily be length or fred or green as 102.
This mirrors reality. For example you might have an array to store a group of people, perhaps starting in order of age. And you could re-sort the list by different properties, like alphabetical by last name, or by height, etc.
But if we look at the objects within that array, it really makes no sense to talk about the order of firstName, lastName, height, weight, age, etc. There isn't really any "order" to speak of: weight doesn't have to come before height, or vice versa. And some people may like to see Last,First, while others prefer First Last. These properties are things we mostly want to be able to access directly by name, so an array isn't really ideal. We want named properties. Hence an object. Don't be confused just because you chose numbers as your property names...they're still names, not indices.
However it is of course possible to iterate all the properties of an object, and it is even possible to control the order in which you iterate them. Traditionally in javascript this iteration was done with the for...in syntax, which goes all the way back to es1. But you couldn't control the order in which the object's keys were iterated. To control order we would have to use for...in to populate an array of keys, then sort the array, then re-loop over the array.
However, it is possible in the newer es6 javascript world to iterate in some great new ways. For example, you can use Object.keys() to get an array of all the object keys (property names), and then you could sort this array. Saves the step of populating an array with for...in.
Another more advanced possibility in es6 (which uses Object.keys) is to actually make the object itself iterable by adding a Symbol.iterator. Again, this only works in es6+.
However the Symbol.iterator gives you a lot of power. This is what it looks like:
query[Symbol.iterator] = function*() {
let properties = Object.keys(this).sort();
for(let p of properties) {
yield {key:p, value:this[p]}
}
}
Once you add this iterator to the object, now you can use things like for...of. And in this example I added a .sort(), so this would iterate over the object's properties in ascending numeric order by key: 102, 421, 736. And since we are yielding an object with key and value, we are still able to see the key value, which we would NOT have if we had just translated to an array.
for(let {key,value} of query) {
console.log(key);
}
I've never asked a question on here but here goes.
Lets say I have an array (named whatever) that looks like this when displayed:
[[{name: "Joe", price: 42}],[{name: "Smith", price: 34}],[{name: "Jerry", price: 67}]]
And I want to do something like whatever[1].price (this fails in my program) I want to be able to take one of the arrays in whatever and retrieve it like whatever[1].price. Any way to do this similar to an ArrayName[index].key ?
first, your JSON is not correct, see the updated one;
since inner element of array is an array with single item so you can access it with 0 index.
var test = [[{name: "Joe", price: 42}],[{name: "Smith", price: 34}],[{name: "Jerry", price: 67}]];
test.forEach(item=> {
console.log(item[0]['price'])
});
Why does an Array of Objects be stored in an another array? Just remove the extra array initialization if you just want to achieve this
And I want to do something like whatever[1].price
Change the data like this:
[{name: "Joe", price: 42}],[{name: "Smith", price: 34}],[{name: "Jerry", price: 67}]
If you can't change the data, then A.T.'s solution will suffice
Well, based on your response ( which have an unnecessary array which contain an array of objects ) you can access to your data like
whatever[0][0].price
The better way is to change your response in backend to get an array of objects then you can access it like normal
whatever[0].price
I have a rather large JSON object being generated via PHP. It creates a PHP object out of a database, with keys that are integers, ie 1-100. These keys are not in that order though, they are in a random order, such as 55, 72, 5, 8, 14, 32, 64, etc. I then use json_encode to output the object as JSON. I then use an AJAX call to grab that JSON and store it in a variable. However, that variable has the JSON object in order 1-100, instead of the sorted order above.
Any ideas why it's doing that, and how I can fix it?
JSON objects have no specific order and are not guaranteed to keep the order you put things in. If you want keys in an order, you should put them in an array which will maintain order. If you want an ordered set of key/value pairs, you can use several different forms.
The simplest would be to just have a single array that is an alternating set of key, value:
var data = ["key1", "value1", "key2", "value2",...];
Or, you could do an array of objects:
var data = [{key: "key1", data: "value1"}, {key: "key2", data: "value2"}, {...}]
Keys within an object aren't technically ordered. That you expect them to be in a particular order is a mistake in data structure. A JSON parser will interpret numerical keys as array positions.
this
{
55: "foo",
29: "bar",
...
}
is semantically the same as:
object[55] = "foo"
object[29] = "bar"
which is:
[
...
"bar" //index 29
...
"foo" //index 55
...
]
Instead, you should separate the order and the identify of your objects:
[
{id: 55, content: "foo"},
{id: 29, content: "bar"},
...
]