I'm trying to make an event-based calendar by iterating through an array of json objects with individual dates using javascript.
What I want to achieve is a new structure from these objects, where i get the year from the object and make that a unique key which can contain multiple months as keys retrieved from the objects, which then again can contain multiple days as keys retrieved from the objects, which again contains multiple objects... phew..
F.ex., say I have this json file:
"objects": [
{
"dateTime": {
"date": "2016-12-24"
},
"values": {
"value1": "some value",
"value2": 700
}
}, {
"dateTime": {
"date": "2016-12-24"
},
"values": {
"value1": "other value",
"value2": 3100
}
}, {
"dateTime": {
"date": "2016-12-25"
},
"values": {
"value1": "random value",
"value2": 300
}
}, {
"dateTime": {
"date": "2017-01-02"
},
"values": {
"value1": "value",
"value2": 100
}
}]
Now I want to iterate through each object and make something like this:
[{
"2017": [{
"january": [{
"monday": [
object
]
}]
},
"2016": {
"december": [{
"saturday": [
object,
object
],
"sunday": [
object
]
}]
}]
}]
So I don't want any duplicates of any object which is set as key. What path should I go for? I've been looking into Map, WeakMap, Set and WeakSet, but I just can't figure out how to do this properly.
Related
I have a large JSON payload and I want to format, the specific object of the payload using JS.
I want flightdetails array object to edit and remove the special characters from it. How can I achieve this?
I have been working on this using XSLT for the past 2 days, and I went nowhere hence I decided to remove it using JS.
Example of the array(there can be more than 30 records inside the flightdetails)
"flightdetails": [
{
"id": XF-2092,
"trips": 2,
"categories": {
"flights": [
"\"return\",\"oneway\""
]
},
"id": XF-2093,
"trips": 1,
"categories": {
"flights": [
"\"return\""
]
}
}
]
Expected Output
"flightdetails": [
{
"id": XF-2092,
"trips": 2,
"categories": {
"flights": [
"return","oneway"
]
},
"id": XF-2093,
"trips": 1,
"categories": {
"flights": [
"return"
]
}
}
]
The flightdetails object inside the //destinations/flightdetails path
I am using pouchdb and have a document structure like this:
{
"_id": "1",
"title": "Title",
"categories": {
"category1": {
"salesx": [
{
"date": "2016-09-15 00:00:00",
"qty": "2"
},
{
"date": "2016-09-16 00:00:00",
"qty": "3"
}
],
"salesy": [
[
{
"date": "2016-09-15 00:00:00",
"qty": "1"
}
]
]
}
},
"_rev": "rev"
}
I now want to get something like this as a result from pouchdb:
{
"_id": "1",
"title": "Title",
"categories": {
"category1": {
"salesx": 2 + 3 = 5,
"salesy": [
[
{
"date": "2016-09-15 00:00:00",
"qty": "1"
}
]
]
}
},
"_rev": "rev"
}
So, salesx should be grouped and the qty should be summarized.
salesy should not be changed.
I also want to add a where clause to the date field.
I tried to start with a map function which selects the correct dates. But I don't know what to emit to group the qty later.
function myMapFunction(doc) {
doc.categories.forEach(category => {
category.salesx.forEach(salex => {
if (salex.date >= mydate) {
emit(?)
}
})
})
}
I can't find a good example on pouchdb docs. They only provide examples for grouping multiple documents together.
Does anyone know how I can achieve grouping the document?
I modified the documents like below, to convert the qty field from string values to number values, to be able to do math operations:
{
"_id": "sale0000",
"_rev": "2-5cd6fff48f9fd099481d3b523ff1191f",
"title": "Title",
"categories": {
"category1": {
"salesx": [
{
"date": "2016-09-15 00:00:00",
"qty": 2
},
{
"date": "2016-09-16 00:00:00",
"qty": 3
}
],
"salesy": [
[
{
"date": "2012-09-15 00:00:00",
"qty": 1
}
]
]
}
}
}
As you mentioned in the comments:
All documents look exactly like the one I already showed. Except the
number of entries in salesx and the number of categories (e.g.
category1, category2 ...) is modified
Based on your above statement, I created in my sample database some documents with varying number of entries in salesx and varying number of categoiry1, category2, etc., but each salesy has only one entry.
Here is another one of my sample documents:
{
"_id": "sale0002",
"_rev": "3-12bf5c872fc124c1f0a5a4a108cb4f7a",
"title": "Title",
"categories": {
"category1": {
"salesx": [
{
"date": "2016-09-15 00:00:00",
"qty": 2
},
{
"date": "2016-09-16 00:00:00",
"qty": 3
},
{
"date": "2017-10-16 00:00:00",
"qty": 9
}
],
"salesy": [
[
{
"date": "2014-09-15 00:00:00",
"qty": 1
}
]
]
},
"category2": {
"salesx": [
{
"date": "2018-01-15 00:00:00",
"qty": 2
},
{
"date": "2012-08-16 00:00:00",
"qty": 3
},
{
"date": "2015-10-16 00:00:00",
"qty": 7
}
],
"salesy": [
[
{
"date": "2011-03-15 00:00:00",
"qty": 1
}
]
]
}
}
}
I'm not sure if I understand what exactly you intend, but I developed the following view map function:
function (doc) {
if(doc.categories){
for(var categ in doc.categories){
var salesx_qty_sum=0;
for(var i=0, len=doc.categories[categ].salesx.length; i<len; i++){
salesx_qty_sum += doc.categories[categ].salesx[i].qty
}
emit(
doc.categories[categ].salesy[0][0]['date'], //emit the date of salesy as the key
//my understanding is that you need to index/sort
//according to date of salesy
[
salesx_qty_sum, //emit the sum of qty for salesx as value
doc.categories[categ].salesy[0][0]['qty'] //emit qty for salesy (unchanged) as value
]
);
}
}
}
In my sample database I created four documents like yours with different number of entries in salesx and also varying number of categories. There is only one entry inside each salesy:
$ curl -k -X GET 'https://admin:****#192.168.1.106:6984/sample/_all_docs'
{"total_rows":53,"offset":0,"rows":[
...
...
{"id":"_design/by_date","key":"_design/by_date","value":{"rev":"20-04cb881624aa819dac13f69c688f2124"}},
...
...
{"id":"sale0000","key":"sale0000","value":{"rev":"2-5cd6fff48f9fd099481d3b523ff1191f"}},
{"id":"sale0001","key":"sale0001","value":{"rev":"2-e8ee019fb0ad076b82d3f4772f736559"}},
{"id":"sale0002","key":"sale0002","value":{"rev":"3-12bf5c872fc124c1f0a5a4a108cb4f7a"}},
{"id":"sale0003","key":"sale0003","value":{"rev":"2-6d40368ddd16b9d02b908ea95d061c7e"}}
]}
The above view map (named by_date) is indexing my documents like below, in which the key is the date of salesy. Based your description, I assume there should be only one entry in each salesy in each category. Also, the value below is an array in which first element is sum of qty for salesx, and the second element is unchanged qty of salesy:
$ curl -k -X GET 'https://admin:admin#192.168.1.106:6984/sample/_design/by_date/_view/by_date'
{"total_rows":6,"offset":0,"rows":[
{"id":"sale0002","key":"2011-03-15 00:00:00","value":[12,1]},
{"id":"sale0000","key":"2012-09-15 00:00:00","value":[5,1]},
{"id":"sale0001","key":"2013-05-20 00:00:00","value":[12,1]},
{"id":"sale0002","key":"2014-09-15 00:00:00","value":[14,1]},
{"id":"sale0003","key":"2015-04-15 00:00:00","value":[5,1]},
{"id":"sale0003","key":"2018-04-05 00:00:00","value":[5,1]}
]}
You can query the by_date view with startkey and endkey to get the results between two dates, like this:
$ curl -k -X GET 'https://admin:admin#192.168.1.106:6984/sample/_design/by_date/_view/by_date?startkey="2013"&endkey="2015"'
{"total_rows":6,"offset":2,"rows":[
{"id":"sale0001","key":"2013-05-20 00:00:00","value":[12,1]},
{"id":"sale0002","key":"2014-09-15 00:00:00","value":[14,1]}
]}
[
{
"May": [
{
"year": 1994,
"date": "2"
},
{
"Sequence": 2,
"Type": "Images"
}
],
"_id": "1122"
}
]
I can get id except "date" which is inside array. And date just show me undefined.
var data = [
{
"May": [
{
"year": 1994,
"date": "2"
},
{
"Sequence": 2,
"Type": "Images"
}
],
"_id": "1122"
}
];
alert(data[0].May[0]["date"]);
You should use arr[i].May[0]['date'], date is inside the object of the 0th index of array May.
Array will be start with the index 0 only . so from your json data 0th position only have the key named "date". So you should use like #void answer.
If you had doubt about whether data is have or not use like below
if(data[0].May[0]["date"])
alert(data[0].May[0]["date"]);
Thank you :)
I have been trying to get nested json data inside columns. The json structure is:
[{
"ratings": [{
"rating": "Detractor",
"employees": [{
"empName": "Pavan",
"quarters": [{
"quarterName": "q1 2015",
"weeks": [{
"weekName": "week1",
"month": "January",
"points": [{
"0": "point1"
}, {
"1": "point2"
}]
}
, {
"weekName": "week2",
"month": "January",
"points": [{
"0": "point1"
}, {
"1": "point2"
}]
}, {
"weekName": "week3",
"month": "January",
"points": [{
"0": "point1"
}, {
"1": "point2"
}]
}
]
}, {
"quarterName": "q2 2015",
"weeks": [{
"weekName": "week4",
"month": "January",
"points": [{
"0": "point1"
}, {
"1": "point2"
}]
}
, {
"weekName": "week5",
"month": "January",
"points": [{
"0": "point1"
}, {
"1": "point2"
}]
}, {
"weekName": "week6",
"month": "January",
"points": [{
"0": "point1"
}, {
"1": "point2"
}]
}
]
}]
}]
}
]
}]
The output should have rating in one column, the corresponding employees in the next and the points in the third column.
I found a solution here, but it deals with only one level and I could not extend it to multiple levels.
I need to display weekly data.
Expected Output
There is no problem accessing nested objects in ui-grid, generally speaking.
In your case the problem seems to be more related to the fact that you have a dynamic structure.
In ui-grid you can assign a value to a column with a string containing the full path for that value, for example:
Suppose you assing ratings sub-array to gridOptions.data, the value of field for week1, week2 and week4 would respectively be:
'employees[0].quarters[0].weeks[0].points[0]'
'employees[0].quarters[0].weeks[1].points[0]'
'employees[0].quarters[1].weeks[0].points[0]'
Now, add to it that the number of weeks and quarters is not fixed and you will find that there is no direct way to programmatically relate the number of the week to the index needed for weeks and quarters array.
I think the best way to handle this would be iterate through the original data you receive and build a new JSON more suited for the grid.
In pseudo code you could do something like this:
initialize results array
iterate through ratings
create new empty object (current_object)
add current_object to results array
iterate through employees
iterate through quarters
iterate through weeks
add value for i-th week as week_i to current_object
I have this JSON Object:
{
"content":
{
"data":
{
"totalCost":244112,
"currency":"USD",
"summary": [
{
"category": "NewCars",
"count": 2,
"cost": 91233,
"details": [
{
"name": "Ferrari",
"Model": "Enzo",
"condtion": "Excellent",
"kms": 10000,
"Year": 2009,
"cost": 69864
},
{
"name": "RollsRoyce",
"Model": "Ghost",
"condtion": "OK",
"kms": 10000,
"Year": 2006,
"cost": 21369
}
]
},
{
"category": "UsedCars",
"count": 2,
"cost": 146464,
"details": [
{
"name": "Buggati",
"Model": "Veyron",
"condtion": "Excellent",
"kms": 10000,
"actionYear": 2011,
"cost": 85500
},
{
"name": "Lamborgini",
"Model": "Aventador",
"condtion": "OK",
"kms": 10000,
"Year": 2010,
"cost": 60964
}
]
},
{
"category": "TwoWheelers",
"count": 1,
"cost": 6415,
"details": [
{
"name": "Suzuki",
"Model": "Hayabusa",
"condtion": "Bad",
"kms": 10000,
"Year":2009,
"cost": 6415
}
]
}
]
}
,"metaData":
{
"title":"Details"
}
}
,"status":200
}
Is there a way to sort the above JSON on the inner keys like name, model, condition, kms, year and cost in Javascript
Thanks in advance. Any help would be appreciated.
P.S. New to JSON and scripts
You can just invoke sort function (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on the array. If it is an inner array of the JSON object, just call the sort on that inner key. The sort function does in place sorting, so even if the array is internal, it will get sorted.
For you example JSON, assuming data variable holds the JSON, following are valid sort invocations.
data.content.data.summary.sort(function(a, b){
//add comparator logic here to define ordering between 2 elements
});
or
data.content.data.summary[0].details.sort(function(a, b){
//add comparator logic here to define ordering between 2 elements
});
Assuming you have parse the JSON already like
var obj = JSON.parse(jsonString);
then you just need to iterate the object so that you can call the sort method on each of the arrays, comparing their items by the desired property:
var propertyname = "name"; // or "Year" or whatever
var summary = obj.content.data.summary;
for (var i=0; i<summary.length; i++)
summary[i].details.sort(function(a, b) {
a = a[propertyname]; b = b[propertyname];
return +(a>b)||-(b>a);
});