I have following output. it gives my API.
{
"_id": {
"year": 2018,
"month": 6,
"day": 11,
"hour": 12,
"interval": 45,
"method": "200"
},
"count": 1
},
{
"_id": {
"year": 2016,
"month": 11,
"day": 11,
"hour": 16,
"interval": 50,
"method": "404"
},
"count": 5
},
{
"_id": {
"year": 2016,
"month": 11,
"day": 11,
"hour": 17,
"interval": 10,
"method": "200"
},
"count": 47
}}
I want to Push them to arrays according to method. As an example
twoHundArray=[
{ "x":2018,6,11,12,45,
"y" :1},
{"x": 2016,11,11,17,10 ,
"y" :47}]
fourhundrArry=[{ "x":2018,11,11,16,50,
"y" :5}]
without using if/else statement how to push them to different arrays. In here I don't know all the names of methods.so cannot use if statement for "method".that is the problem here.
The original object is invalid. You can't have elements in an object without specifying the keys. I've assumed that it is an array.
Secondly, there is no way of pushing elements to different arrays without knowing their names. So the judgement of pushing the elements to different variables will have to be based on if/else conditions. Additionally, creation of those variables will vary based on the groups, as method could have been any value.
If you agree to group the objects based on the values method have, here is a way to do this:
const data = [{"_id":{"year":2018,"month":6,"day":11,"hour":12,"interval":45,"method":"200"},"count":1},{"_id":{"year":2016,"month":11,"day":11,"hour":16,"interval":50,"method":"404"},"count":5},{"_id":{"year":2016,"month":11,"day":11,"hour":17,"interval":10,"method":"200"},"count":47}];
const res = {};
data.forEach(item => {
const { method, ...obj } = item['_id'];
res[method] = res[method] || [];
res[method].push({
x: Object.values(obj),
y: item.count
});
});
console.log(res);
It creates an object, whose keys are method. The values in the object are the arrays, which contain the items grouped by method.
You can use Array.reduce and create a map based on method. Try the following:
var data = [{
"_id": {
"year": 2018,
"month": 6,
"day": 11,
"hour": 12,
"interval": 45,
"method": "200"
},
"count": 1
},
{
"_id": {
"year": 2016,
"month": 11,
"day": 11,
"hour": 16,
"interval": 50,
"method": "404"
},
"count": 5
},
{
"_id": {
"year": 2016,
"month": 11,
"day": 11,
"hour": 17,
"interval": 10,
"method": "200"
},
"count": 47
}];
var method = data.reduce((a,o)=>{
if(!a[o._id.method]){
a[o._id.method] = [];
};
var { method, ...ob } = o._id;
a[o._id.method].push({
"x": Object.values(ob).join(","),
"y" : o.count
});
return a;
}, {});
console.log(method);
You can create an object with status:values key/pair using Array.reduce and post that using Object destructuring and default assignment, create independent variables.
const arr = [{"_id":{"year":2018,"month":6,"day":11,"hour":12,"interval":45,"method":"200"},"count":1},{"_id":{"year":2016,"month":11,"day":11,"hour":16,"interval":50,"method":"404"},"count":5},{"_id":{"year":2016,"month":11,"day":11,"hour":17,"interval":10,"method":"200"},"count":47}];
let obj = arr.reduce((a,c) => {
a[c._id.method] = a[c._id.method] || [];
a[c._id.method].push({"x" : Object.values(c._id).join(), "y" : c.count});
return a;
},{});
/* You can add an entry here for every status type, it will pick the
** value from object and if not present will be defaulted to an empty array */
const {200 : twoHundArray=[], 404 : fourHundArray=[], 300 : threeHundArray=[]} = obj;
console.log(twoHundArray);
console.log(fourHundArray);
console.log(threeHundArray);
#Palani, I'll suggest you to use an object to gather all the required information.
Please have a look at the below code and let me know any suggestions/modifications if you need.
var timeDataArr = [
{
"_id": {
"year": 2018,
"month": 6,
"day": 11,
"hour": 12,
"interval": 45,
"method": "200"
},
"count": 1
},
{
"_id": {
"year": 2016,
"month": 11,
"day": 11,
"hour": 16,
"interval": 50,
"method": "404"
},
"count": 5
},
{
"_id": {
"year": 2016,
"month": 11,
"day": 11,
"hour": 17,
"interval": 10,
"method": "200"
},
"count": 47
}
]
// An object that maps 'method' to its related data array
var newTimeData = {}
for(var timeData of timeDataArr) {
var obj = timeData["_id"];
var arr = [obj["year"], obj["month"], obj["day"], obj["hour"], obj["interval"]];
var newObj = {
"x": arr.join(", "),
"y": timeData["count"],
}
if(newTimeData[obj["method"] + "Array"]) { // method found
newTimeData[obj["method"] + "Array"].push(newObj)
} else { // method not found
newTimeData[obj["method"] + "Array"] = [newObj]
}
}
// PRETTY PRINTING OBJECT
console.log(JSON.stringify(newTimeData, undefined, 4))
/*...
{
"200Array": [
{
"x": "2018, 6, 11, 12, 45",
"y": 1
},
{
"x": "2016, 11, 11, 17, 10",
"y": 47
}
],
"404Array": [
{
"x": "2016, 11, 11, 16, 50",
"y": 5
}
]
}
...*/
// PRETTY PRINTING ARRAY POINTED BY '200Array' key
console.log(JSON.stringify(newTimeData["200Array"], undefined, 4))
/*...
[
{
"x": "2018, 6, 11, 12, 45",
"y": 1
},
{
"x": "2016, 11, 11, 17, 10",
"y": 47
}
]
...*/
// PRETTY PRINTING ARRAY POINTED BY '404Array' key
console.log(JSON.stringify(newTimeData["404Array"], undefined, 4))
/*...
[
{
"x": "2016, 11, 11, 16, 50",
"y": 5
}
]
...*/
Output ยป
H:\RishikeshAgrawani\Projects\Sof\FilterArrays>node FilterArrays.js
{
"200Array": [
{
"x": "2018, 6, 11, 12, 45",
"y": 1
},
{
"x": "2016, 11, 11, 17, 10",
"y": 47
}
],
"404Array": [
{
"x": "2016, 11, 11, 16, 50",
"y": 5
}
]
}
[
{
"x": "2018, 6, 11, 12, 45",
"y": 1
},
{
"x": "2016, 11, 11, 17, 10",
"y": 47
}
]
[
{
"x": "2016, 11, 11, 16, 50",
"y": 5
}
]
Related
My JSON file has the dates separated like this:
"time": {
"date": {
"year": 2018,
"month": 2,
"day": 25
},
"time": {
"hour": 10,
"minute": 19,
"second": 6,
"nano": 19000000
}
},
The tutorial I used to get a line graph in d3 going was in this link:
https://datawanderings.com/2019/10/28/tutorial-making-a-line-chart-in-d3-js-v-5/
Using the code below:-
const timeConv = d3.timeParse("%d-%b-%Y");
const dataset = d3.csv(datacsv);
dataset.then(function(data) {
var slices = data.columns.slice(1).map(function(id) {
return {
id: id,
values: data.map(function(d){
return {
date: timeConv(d.date),
measurement: +d[id]
};
})
};
});
});
How could I use the same code but use the JSON file with the separated date values?
Just make up the actual date string from the separate dates:
return {
date: timeConv(d.time.date.day + '-' + d.time.date.month + '-' + d.time.date.year),
measurement: +d[id]
};
Since the month is not described as the abbreviated month name, you need to change timeConv as
const timeConv = d3.timeParse("%d-%m-%Y");
An json data example:
let dataset = [{
"id": 1,
"time": {
"date": {
"year": 2018,
"month": 2,
"day": 25
},
"time": {
"hour": 10,
"minute": 19,
"second": 6,
"nano": 19000000
}
}
}, {
"id": 2,
"time": {
"date": {
"year": 2019,
"month": 2,
"day": 25
},
"time": {
"hour": 10,
"minute": 19,
"second": 6,
"nano": 19000000
}
}
}]
const timeConv = d3.timeParse("%d-%m-%Y");
newData = dataset.map(function(d) {
return {
date: timeConv(d.time.date.day + '-' + d.time.date.month + '-' + d.time.date.year),
measurement: +d.id
}
})
console.log(newData)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
I have an JS object data, from this array of object, I need to take "amount" value which is inside of "limitBreakup" Array. I have done using .map(), But I am intersted to know the implementation of the same using Recursion.
var data = [
{
"limitRequirementId":"123",
"facilityType":"cc",
"amount":800000,
"existingRoi":12,
"existingPf":12100,
"repoRate":5,
"spread":10,
"tenure":24,
"margin":10000,
"loanVariable":{
"type":"roi/commission",
"value":15
},
"limitBreakup":[
{
"limitRequirementId":"13",
"facilityType":"cc",
"repoRate":5,
"amount":8000,
"spread":10,
"tenure":24,
"margin":100,
"loanVariable":{
"type":"roi/commission",
"value":15
}
},
{
"limitRequirementId":"22",
"facilityType":"LC",
"repoRate":4,
"amount":900,
"spread":6,
"tenure":21,
"margin":15,
"loanVariable":{
"type":"roi/commission",
"value":10
}
}
]
},
{
"limitRequirementUniqueId":"13",
"limitRequirementId":"13",
"facilityType":"lc",
"amount":900000,
"existingRoi":10,
"existingPf":1000,
"repoRate":3,
"spread":1,
"tenure":21,
"margin":1000,
"loanVariable":{
"type":"roi/commission",
"value":15
},
"limitBreakup":[
{
"limitRequirementId":"35",
"facilityType":"CC",
"repoRate":6,
"amount":600,
"spread":8,
"tenure":28,
"margin":13,
"loanVariable":{
"type":"roi/commission",
"value":14
}
}
]
}
]
My Solution using normal iteration works:
data.forEach((d, i)=>{
let limitBreakup = d.limitBreakup;
if(Array.isArray(limitBreakup)){
limitBreakup.forEach((l)=>{ console.log(l, '->', l.amount) })
}else{
console.log(limitBreakup, 'else->', limitBreakup.amount)
}
//console.log(d.limitBreakup);
})
But using Recursion, I am half way:
https://jsfiddle.net/1g98sLw3/2/
http://www.mocky.io/v2/5ea974eb3400005e003f0203 (Since the json object is very big, I have pasted in mocky.io for reference)
Something like this should work
Demo proof: https://jsfiddle.net/do58kj3q/
You need a loop to pass through your objects and then add them to the array when you meet the criteria
var data = [{
"limitRequirementId": "123",
"facilityType": "cc",
"amount": 800000,
"existingRoi": 12,
"existingPf": 12100,
"repoRate": 5,
"spread": 10,
"tenure": 24,
"margin": 10000,
"loanVariable": {
"type": "roi/commission",
"value": 15
},
"limitBreakup": [{
"limitRequirementId": "13",
"facilityType": "cc",
"repoRate": 5,
"amount": 8000,
"spread": 10,
"tenure": 24,
"margin": 100,
"loanVariable": {
"type": "roi/commission",
"value": 15
}
},
{
"limitRequirementId": "22",
"facilityType": "LC",
"repoRate": 4,
"amount": 900,
"spread": 6,
"tenure": 21,
"margin": 15,
"loanVariable": {
"type": "roi/commission",
"value": 10
}
}
]
},
{
"limitRequirementUniqueId": "13",
"limitRequirementId": "13",
"facilityType": "lc",
"amount": 900000,
"existingRoi": 10,
"existingPf": 1000,
"repoRate": 3,
"spread": 1,
"tenure": 21,
"margin": 1000,
"loanVariable": {
"type": "roi/commission",
"value": 15
},
"limitBreakup": [{
"limitRequirementId": "35",
"facilityType": "CC",
"repoRate": 6,
"amount": 600,
"spread": 8,
"tenure": 28,
"margin": 13,
"loanVariable": {
"type": "roi/commission",
"value": 14
}
}]
}
]
var array=[];
function recursiveCounter(arr) {
for (let i = 0; i < arr.length; i++) {
const obj = arr[i];
if (!obj.limitBreakup) {
array.push(obj.amount);
}
if (Array.isArray(obj.limitBreakup)) {
recursiveCounter((obj.limitBreakup));
}
}
}
recursiveCounter(data);
console.log(array)
I have parsed a csv file which gives me an array like this:
[{
"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52
},
{
"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52
}]
I want to merge minute,hour,day,month,year to a single key. Like this:
"time": "2019-07-02 09:57:35"
so i can use this as a datetime object on my API.
The way I am currently getting data is:
const cleanKeys = [
'year',
'month',
'day',
'hour',
'minute',
'temperature',
];
const dataAsObject = totalData.map(function (values) {
return cleanKeys.reduce(function (o, k, i) {
o[k] = values[i];
return o;
}, {})
});
This is basically adding a header key to all data. I am only interested in merging minute, hour, day, month, year column.
I suggest you to use built in Date constructor:
var obj = {"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52};
const date = new Date(obj.year, obj.month - 1, obj.day, obj.hour, obj.minute);
const newObj = {date, temperature: obj.temperature};
console.log(JSON.stringify(newObj));
EDIT:
please find below updated answer using date in loop:
const arr = [{
"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52
},
{
"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52
}];
const newArr = arr.reduce((a,c) => {
const date = new Date(c.year, c.month - 1, c.day, c.hour, c.minute);
a.push({date, temperature: c.temperature});
return a;
}, []);
console.log(JSON.stringify(newArr));
You can create the string yourself, e.g.:
yourArray["time"] = `${yourArray.year}-${yourArray.month}-${yourArray.day} ${yourArray.hours}:${yourArray.minutes}:${yourArray.seconds}`;
I am trying to loop through a json file for all the total and first_record values. The key is
json.STATION[0].OBSERVATIONS.precipitation[0].total
I'm trying to return a result:
[20180116, 0.8], [20180117, 0.0] . . .
I've tried a variety of approaches. My best result has been the classic undefined
Below is a snippet from the jsfiddle I have been working on. The json is generated by mesowest.net api.
Once I have this sorted out I am hoping to plot the values in highcharts. thanks.
const data = {
"UNITS": {
"precipitation": "Inches"
},
"STATION": [{
"STATUS": "ACTIVE",
"MNET_ID": "25",
"PERIOD_OF_RECORD": {
"start": "20000120",
"end": "20180121"
},
"ELEVATION": "6340",
"NAME": "BOGUS BASIN",
"RESTRICTED": false,
"STID": "BOGI1",
"ELEV_DEM": "6362",
"LONGITUDE": "-116.09685",
"STATE": "ID",
"OBSERVATIONS": {
"precipitation": [{
"count": 23,
"first_report": "20180115",
"interval": 1,
"report_type": "precip_accum",
"last_report": "20180115",
"total": 0.0
}, {
"count": 24,
"first_report": "20180116",
"interval": 2,
"report_type": "precip_accum",
"last_report": "20180116",
"total": 0.2
}, {
"count": 24,
"first_report": "20180117",
"interval": 3,
"report_type": "precip_accum",
"last_report": "20180117",
"total": 0.0
}, {
"count": 24,
"first_report": "20180118",
"interval": 4,
"report_type": "precip_accum",
"last_report": "20180118",
"total": 0.0
}, {
"count": 24,
"first_report": "20180119",
"interval": 5,
"report_type": "precip_accum",
"last_report": "20180119",
"total": 0.8
}, {
"count": 24,
"first_report": "20180120",
"interval": 6,
"report_type": "precip_accum",
"last_report": "20180120",
"total": 0.0
}, {
"count": 13,
"first_report": "20180121",
"interval": 7,
"report_type": "precip_accum",
"last_report": "20180121",
"total": 0.0
}]
},
"LATITUDE": "43.76377",
"TIMEZONE": "America\/Boise",
"ID": "1160"
}],
"SUMMARY": {
"DATA_QUERY_TIME": 1.6429424286,
"RESPONSE_CODE": 1,
"RESPONSE_MESSAGE": "OK",
"METADATA_RESPONSE_TIME": "0.0920295715332 ms",
"NUMBER_OF_OBJECTS": 1,
"PRECIP_DATA_TIME": 2.4950504303,
"DATA_PARSE_TIME": 0.8418560028
}
};
console.log(data.STATION[0].OBSERVATIONS.precipitation[4].total);
document.getElementById("demo").innerHTML = data.STATION[0].OBSERVATIONS.precipitation[4].total;
const totl = data.STATION[0].OBSERVATIONS.precipitation[0].total;
console.log(totl);
//
var i, precipitation;
for (i = 0; i < data.STATION[0].OBSERVATIONS.precipitation.total.length; i++) {
precip = data.STATION[0].OBSERVATIONS.precipitation[i].total;
}
console.log(precip);
//console.log(obj);
<p id="demo"></p>
First off, in your for loop you are referring to data.STATION[0].OBSERVATIONS.precipitation.total.length, but the total part isn't even defined there. It's have to be precipitation[0].total for it to be anything, and even then, it isn't an array. You just want:
data.STATION[0].OBSERVATIONS.precipitation.length
Also, just code-style wise, stick that into a variable so you don't have to type that craziness over and over. It'll also help avoid typos:
const records = data.STATION[0].OBSERVATIONS.precipitation;
You also are just setting the same value back to a variable over and over, so at the end, you'd only have the last value. You want to stick them in an array.
const totals = [];
for (let i = 0; i < records.length; i++) {
totals.push(records[i].total);
}
If you want both total and first_report, you can either do parallel arrays:
const totals = [];
const firsts = [];
for (let i = 0; i < records.length; i++) {
totals.push(records[i].total);
firsts.push(records[i].first_record);
}
or have an array of arrays:
const results = [];
for (let i = 0; i < records.length; i++) {
results.push([records[i].total, records[i].first_record]);
}
Here is a working example:
const data = {
"UNITS": {
"precipitation": "Inches"
},
"STATION": [{
"STATUS": "ACTIVE",
"MNET_ID": "25",
"PERIOD_OF_RECORD": {
"start": "20000120",
"end": "20180121"
},
"ELEVATION": "6340",
"NAME": "BOGUS BASIN",
"RESTRICTED": false,
"STID": "BOGI1",
"ELEV_DEM": "6362",
"LONGITUDE": "-116.09685",
"STATE": "ID",
"OBSERVATIONS": {
"precipitation": [{
"count": 23,
"first_report": "20180115",
"interval": 1,
"report_type": "precip_accum",
"last_report": "20180115",
"total": 0.0
}, {
"count": 24,
"first_report": "20180116",
"interval": 2,
"report_type": "precip_accum",
"last_report": "20180116",
"total": 0.2
}, {
"count": 24,
"first_report": "20180117",
"interval": 3,
"report_type": "precip_accum",
"last_report": "20180117",
"total": 0.0
}, {
"count": 24,
"first_report": "20180118",
"interval": 4,
"report_type": "precip_accum",
"last_report": "20180118",
"total": 0.0
}, {
"count": 24,
"first_report": "20180119",
"interval": 5,
"report_type": "precip_accum",
"last_report": "20180119",
"total": 0.8
}, {
"count": 24,
"first_report": "20180120",
"interval": 6,
"report_type": "precip_accum",
"last_report": "20180120",
"total": 0.0
}, {
"count": 13,
"first_report": "20180121",
"interval": 7,
"report_type": "precip_accum",
"last_report": "20180121",
"total": 0.0
}]
},
"LATITUDE": "43.76377",
"TIMEZONE": "America\/Boise",
"ID": "1160"
}],
"SUMMARY": {
"DATA_QUERY_TIME": 1.6429424286,
"RESPONSE_CODE": 1,
"RESPONSE_MESSAGE": "OK",
"METADATA_RESPONSE_TIME": "0.0920295715332 ms",
"NUMBER_OF_OBJECTS": 1,
"PRECIP_DATA_TIME": 2.4950504303,
"DATA_PARSE_TIME": 0.8418560028
}
};
const records = data.STATION[0].OBSERVATIONS.precipitation;
const results = [];
for (let i = 0; i < records.length; i++) {
results.push([records[i].total, records[i].first_report]);
}
console.log(results);
FWIW, your key is not precipitation[0] but you want to iterate through all precipitation elements:
// precipitation is an array, so it supports Array.prototype.map()
var output = data.STATION[0].OBSERVATIONS.precipitation.map(function(p) {
return [p.first_report, p.total] });
see also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
I make an AJAX request and I receive this (looking at the Network tab)
[
{
"request": "Amount of rainfall by day",
"days": [
{
"day": 1,
"amount": 50
}, {
"day": 2,
"amount": 10
}, {
"day": 3,
"amount": 10
}, {
"day": 4,
"amount": 150
}, {
"day": 5,
"amount": 130
}, {
"day": 6,
"amount": 45
}, {
"day": 7,
"amount": 10
}
]
}
]
I would like to create an array with the values of 'amount'.
[50,10,10,150,130,45,10]
(the order is important; I will show these values in a chart with chronological order)
I tried lodash.values as well as for..in but the mix between nested arrays and nested objects is rather confusing.
I would like an elegant solution.
Question 1: Should I use a Json method to remove the outside root level array ? Any way to get rid of it?
Question 2: Which data structure should I use in order to keep the relation between days and amounts? (my charting library, Chart.js receives a simple array of single values.
Use Array#map to create a new array from the requested values:
var data = [{"request":"Amount of rainfall by day","days":[{"day":1,"amount":50},{"day":2,"amount":10},{"day":3,"amount":10},{"day":4,"amount":150},{"day":5,"amount":130},{"day":6,"amount":45},{"day":7,"amount":10}]}];
var result = data[0].days.map(function(obj) {
return obj.amount;
});
console.log(result);
Question 1
You can tranverse it easily by using data[0], and after you'll map / reduce, you'll get a new data structure.
Question 2
You can use a simple object, with two related arrays by using Array#reduce:
var data = [{"request":"Amount of rainfall by day","days":[{"day":1,"amount":50},{"day":2,"amount":10},{"day":3,"amount":10},{"day":4,"amount":150},{"day":5,"amount":130},{"day":6,"amount":45},{"day":7,"amount":10}]}];
var result = data[0].days.reduce(function(r, o) {
r.days.push(o.day);
r.amounts.push(o.amount);
return r;
}, { days: [], amounts: [] });
console.log(JSON.stringify(result));
I use the Lodash to answer your question
var response = [
{
"request": "Amount of rainfall by day",
"days": [
{
"day": 1,
"amount": 50
}, {
"day": 2,
"amount": 10
}, {
"day": 3,
"amount": 10
}, {
"day": 4,
"amount": 150
}, {
"day": 5,
"amount": 130
}, {
"day": 6,
"amount": 45
}, {
"day": 7,
"amount": 10
}
]
}
];
// using _.map function
_.map(response[0].days, 'amount');
Lodash
Use this:
var reply = [
{
"request": "Amount of rainfall by day",
"days": [
{
"day": 1,
"amount": 50
}, {
"day": 2,
"amount": 10
}, {
"day": 3,
"amount": 10
}, {
"day": 4,
"amount": 150
}, {
"day": 5,
"amount": 130
}, {
"day": 6,
"amount": 45
}, {
"day": 7,
"amount": 10
}
]
}
];
var amounts = reply[0].days.map((i) => { return i.amount });
console.log(amounts);
In case the day property value does not follow the order of the elements in the response object, you may need to use that value as index in your final array. Here is an ES6 solution:
var response = [
{
"request": "Amount of rainfall by day",
"days": [
{
"day": 1,
"amount": 50
}, {
"day": 2,
"amount": 10
}, {
"day": 3,
"amount": 10
}, {
"day": 4,
"amount": 150
}, {
"day": 5,
"amount": 130
}, {
"day": 6,
"amount": 45
}, {
"day": 7,
"amount": 10
}
]
}
];
var arr = response[0].days.reduce( (arr, o) => (arr[o.day-1] = o.amount, arr), []);
console.log(arr);
So this would even work if the value for day 4 were missing. The value at the corresponding index in the output array (index 3) would have undefined in that case.