Sort nested objects in Array in Javascript - javascript

I receive an object from MongoDB request.
Below is a snippet of it:
{
"Kost": "Kost1",
"Name": "Name1",
"inventar": [
{
"data": "A",
"name": "thefirst",
"ean": "802.0165.813",
},
{
"ean": "802.6725.277",
"name": "thesecond",
"data": "B",
},
{
"ean": "570.6761.483",
"name": "thethird",
"data": "C",
},
{
"ean": "570.6764.519",
"name": "thefourth",
"data": "D",
}
]
}
Later, I will create a table in Jade with this code:
table(border='1', cellspacing='3', cellpadding='4')
tr
th(align='center') ean
th(align='center') name
th(align='center') data
each obj in inventar
tr
each val in obj
td= val
The problem is, that the objects in the Array "inventar" are not sorted. The table has a wrong structure. The current output of the table looks like:
|ean | name | data
--------------------------------------------
|802.0165.813| thefirst | A
|B | thesecond | 802.6725.277
|C | thethird | 570.6761.483
|D | thefourth | 570.6764.519
The first column must be the ean, second the name and third the data. Only the first row is correct. I think its luck.
Its possible to sort the objects in the Array ("inventar") before iterating over it, to get the right structure?
I read somewhere that it is not possible to sort directly in mongoose.
thanks in advance

It appears you are asking about the property order in the object. In ES5 and earlier, properties have NO deterministic order by specification. There are some implementations that will maintain the order the properties were created in, but that was not guaranteed.
In ES6, the spec has been changed to say that properties will remain in the order they are created. But, there is no mechanism for reordering properties on an existing object. If you want to change the order, the work-around would be to create a new object, copy the properties over in the desired order and then replace the original object with the new one.
All that said, normal coding should not care what order the properties are in. You refer to a property on an object as in x.inventar[0].data and it should not matter whether data is the first or last property when you dump the object contents.
Given what you are showing in your sample table, it appears that some piece of code is grabbing the first property and putting it in the first column. That is the wrong way to build the table. Instead, it should grab a specific property name and then the order of the properties on the object simply will not matter. So, I think what you need to do is to fix your jade definition to refer to specific property names, not to just take them in order.
I don't know Jade very well myself, but I think you can do something like this:
table(border='1', cellspacing='3', cellpadding='4')
tr
th(align='center') ean
th(align='center') name
th(align='center') data
each obj in inventar
tr
//edited syntax
td= obj.ean
td= obj.name
td= obj.data

Related

how to get groupBy() but in other outcome in javascript

I was looking this sandbox
And basically it does what I want but I want in parent element (which is grouped by for) to add property name.
Also, I want to reduce some properties in below, like to remove color in child elements, because I grouped by color?
For example, with my data json looks like:
"stuff": {
"onetype": [
{"id":1,"name":"John Doe"},
{"id":2,"name":"Don Joeh"}
],
"othertype": {"id":2,"company":"ACME"}
},
"otherstuff": {
"thing": [[1,42],[2,2]]
}
or other approach:
I have an array with one-to many key relation:
[1,1]
[1,2]
[2,2]
[3,2]
[4,1]
How to convert to valid json, with one property in root (first element from an array), and its depended children?

Remove all keys from JSON object

Initially I was working with a CSV, where each row contained data e.g.
------------------------------------------------------
123 | cat | dog |
------------------------------------------------------
456 | cat | rabbit |
------------------------------------------------------
789 | snake | dog |
------------------------------------------------------
I am now getting more data with different structure, so I can no longer use a csv. Instead I am using JSON file. The JSON file looks something like this
[
[
{
"ID": 123,
"animal_one": "cat",
"animal_two": "dog"
},
{
"ID": 456,
"animal_one": "cat",
"animal_two": "rabbit"
},
{
"ID": 789,
"animal_one": "snake",
"animal_two": "dog"
}
],
[
2222
],
[
12345
],
[
"2012-01-02"
],
[
"2012-12-20"
]
]
So you can see the additional data. For this part of the application, I only want to work with the first part of the JSON, the part containing animals. The function I have basically works on values only, so I need to make this JSON like the original CSV file, whereby I only have the values, no keys.
So I am loading the JSON file, which is then contained within the variable data
I am then trying something like this
var key = "CUST_ID";
delete data[0][key];
console.log(JSON.stringify(data[0]))
Although this doesnt even work, I think it is the wrong approach anyway. I dont want to define the keys I want removed, I just want it to remove all keys, and keep the values.
How would I go about doing this? I am using data[0] to get the first section of the JSON, the part that contains animals. Not sure if this is correct either?
Thanks
You can simply do this, if you dont care what keys you are getting:
var collection = "";
data[0].forEach(function(row) {
var line = [];
Object.keys(row).forEach(function(key) {
line.push(row[key])
});
collection = collection + line.join(',') + '\n';
})
You will get csv string out of collection
I dont want to define the keys I want removed
You still will need to define which keys you want the values from. One could just take all the values from the object, in arbitrary order, but that's not robust against changes to the data format. Use something like
const table = data[0].map(value => [value.ID, value.animal_one, value.animal_two]);
data[0].forEach(function(row,index) {
data[0][index] = Object.values(data[0][index]);
});

Javascript, JSON - Create Table

I have a JSON Array like:
[{
"name": "abc", "month":"Jan-15","value":xyz
},{
"name": "bcd", "month":"Jan-15","value":xyz
},{
"name": "abc", "month":"Feb-15","value":xyz
},{
"name": "bcd", "month":"Feb-15","value":xyz
}]
No. of "names" may vary from month to month. But no. of "month" stays the same.
I need to create tabular overview:
Name Jan-15 Feb- 15 ...... Dec-15
abc value value ..... value
bcd value value ..... value
I'm new to Javascript and I really don't know how to get values in right columns and rows. Though I know how to dynamically add rows.
Shall I opted for "pure" solution or is better to check for a framework like e.g. AngularJS ?
Edit: I have extracted "Months" and "Names" from array and I need to do something like: value = check for this particular "name" in array and return corresponding "value".
How do I write this in JS?
It depends on the form of your data object. If you have an array object or a string object you need to use JSON.parse in order to be able to use indices and values.
If yes, then you will need to have JSON.parse(data).name to return your name values.
JSON.parse(data).month for your months and of course JSON.parse(data).value to return the xyz values.
If your data is already a JSON object then you will simply use data.name, data.month and data.value accordingly.
These links might help you get into the basics, follow the syntax and the examples.
http://www.w3schools.com/js/js_json.asp
http://www.w3schools.com/json/json_eval.asp
http://www.json.org/js.html and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

Data Structure to represent a DAG in Javascript

I have a string that I need to parse into a graph (DAG) data structure using javascript. Included in the data structure are a few attributes I should store, such as the node's id, name, and a label that is given to the link if one exists to another node. So, an example would be
Node1 (id: 1, name: 'first') --('link name')--> Node2 (id:....)
and so forth. Once the data structure is created I do not need to do any more operations on it other than read it (I will later use it to render a visualization with d3). The amount of nodes will not be very many, as several of them are shared.
I am imagining an adjacency list but am not sure how I would encode that in javascript. For instance, I know a json object can have a "field" : "value" structure but can I do that with Object : [list of adjacent Objects]?
you can use lists (arrays) in json. E.g. I could represent a simple directed graph as
{
"NodeA": {"name": "NodeA", "adjacentTo": ["NodeB", "NodeC"]},
"NodeB": {"name": "NodeB", "adjacentTo": ["NodeC", "NodeD"]},
"NodeC": {"name": "NodeC", "adjacentTo": ["NodeA"]},
"NodeD": {"name": "NodeD", "adjacentTo": []}
}
This would be the graph:
C
^^
| \
| \
A -> B -> D
The name field really isn't needed, but you can associate any attributes you want with a node that way.
JavaScript objects must have string keys, but can store any type of value. Of course, the entire point in an id is to allow you to represent a complex type wirh a simple one.
var adjacentTo = {};
adjacentTo[node1.id] = [node2, node3]

Comparing variable size Objects in Javascript

I'm working on an auto-updating table of information using AJAX, but I've run into a bump in the road. I'm using PHP to return a JSON object on each request, which contains data in the following format:
({
"table": {
"544532": {
"field1": "data",
"field2": "data2",
"field3": "data3",
.....
},
"544525": {
"field1": "data",
"field2": "data2",
"field3": "data3",
.....
},
......
}
}); //
I use Prototype.js to get the list of IDs into an array:
var ids = Object.keys(data.table).sort();
However, random rows of the table could be disappear from the list at any time, and new rows could be added to the end at any time. I assume I would store the array of IDs from the previous request and compare those with the new array, but since random rows can disappear, thus shifting the IDs after that one, how do I compare these so that I can only add new rows or remove deleted rows from the page?
Unfortunately Prototype doesn't include a Set type which would have made things a whole lot simpler. So we'll have to make do with this:
Array.prototype.subtract = function(a){
return this.reject(this.include.bind(a));
}
The above adds a much needed subtract function. We can use it like this:
added_ids = new_ids.subtract(old_ids);
removed_ids = old_ids.subtract(new_ids);
It's not too slow either since some browsers supports indexOf which Prototype's include checks for and uses.
PS. Array already has an intersect function, if you'd like a complement too here it is...
Array.prototype.complement = function(a){
return a.reject(this.include.bind(this));
}
Essentially a.subtract(b) is the same as b.complement(a).
Im sure there are better ways to do this - but you will need to store the rows that are shown in the table somewhere - perhaps an array - then loop the JSON object comparing the rows against the array.
You should update your JSON data structure when the table is updated. That would be that data model for the page. Then you can just call Object.keys(data.table) everytime you need it.

Categories