creating different dataset array - javascript

I am trying to create different dataset based on month value. For eg. for June month one dataset and for July another dataset. But in my code, all the month values are getting combined and created as one dataset.
It will be really helpful who can help me in creating different dataset dynamically. I have attached the fiddle which I tried with my data object
JSFIDDLE
var obj = [{
date: "2017-06-01",
reqC: "129963",
month: "JUNE",
resC: "80522"
}, {
date: "2017-06-05",
reqC: "261162",
month: "JUNE",
resC: "83743"
},{
date: "2017-07-03",
reqC: "438860",
month: "JULY",
resC: "166107"
}]
var maindataset = [];
var dataset = [];
["reqC", "resC"].forEach((series) => {
dataset.push({
seriesname: series,
data: obj.map((el) => {
return el[series]
})
})
});
maindataset.push({
dataset: dataset
});
alert(JSON.stringify(maindataset));
// Expected Output
{
"dataset": [
{
"dataset": [ //June
{
"seriesname": "Req",
"data": [
{
"value": "129963"
},
{
"value": "261162"
}
]
},
{
"seriesname": "Res",
"data": [
{
"value": "80522"
},
{
"value": "83743"
}
]
}
]
},
{
"dataset": [ //July
{
"seriesname": "Req",
"data": [
{
"value": "438860"
}
]
},
{
"seriesname": "Res",
"data": [
{
"value": "166107"
}
]
}
]
}
]
}

You could use a nested hash table and iterate later the keys for the wanted parts.
var data = [{ date: "2017-06-01", reqC: "129963", month: "JUNE", resC: "80522" }, { date: "2017-06-05", reqC: "261162", month: "JUNE", resC: "83743" }, { date: "2017-07-03", reqC: "438860", month: "JULY", resC: "166107" }],
result = { dataset: [] },
parts = { reqC: 'Req', resC: 'Res' },
hash = { _: result.dataset };
data.forEach(function (a) {
var temp = hash;
if (!temp[a.month]) {
temp[a.month] = { _: [] };
temp._.push({ dataset: temp[a.month]._ });
}
temp = temp[a.month];
Object.keys(parts).forEach(function (k) {
if (!temp[k]) {
temp[k] = { _: [] };
temp._.push({ seriesname: parts[k], data: temp[k]._ });
}
temp[k]._.push({ value: a[k] });
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

You can create groups based on month and then you can output the desired data structure. Check the snippet.
var obj = [{
date: "2017-06-01",
reqC: "129963",
month: "JUNE",
resC: "80522"
}, {
date: "2017-06-05",
reqC: "261162",
month: "JUNE",
resC: "83743"
},{
date: "2017-07-03",
reqC: "438860",
month: "JULY",
resC: "166107"
}];
var result = {};
var groups = obj.reduce(function(acc, obj) {
acc[obj.month] = acc[obj.month] || [];
acc[obj.month].push(obj);
return acc;
}, {});
//console.log(groups);
result.dataset = Object.keys(groups).map(function(key) {
return {
dataset: [{
"seriesname" : "Req",
"data": groups[key].map(function(o) {
return { value : o.reqC };
})
}, {
"seriesname" : "Res",
"data": groups[key].map(function(o) {
return { value : o.resC };
})
}]
};
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

You cannot use the same property name for an object twice. You have an object in your data that looks like this:
"data": [
{
"value": "80522"
},
{
"value": "83743"
}
]
Either change the keys to unique ones:
"data": [
{
"value1": "80522"
},
{
"value2": "83743"
}
]
Or make it an array:
"data": [ "80522", "83743" ]

You need to add check for month as well.
Try this:
var obj = [{
date: "2017-06-01",
reqC: "129963",
month: "JUNE",
resC: "80522"
}, {
date: "2017-06-05",
reqC: "261162",
month: "JUNE",
resC: "83743"
},{
date: "2017-07-03",
reqC: "438860",
month: "JULY",
resC: "166107"
}]
var maindataset = [];
["JUNE","JULY"].forEach((month)=>{
var dataset = [];
["reqC", "resC"].forEach((series) => {
dataset.push({
seriesname: series,
data: obj.reduce((filtered, el) => {
if(el["month"] === month){
filtered.push({value: el[series]});
}
return filtered;
},[])
})
});
maindataset.push({
dataset: dataset
});
})
alert(JSON.stringify(maindataset));
output:
[{
"dataset": [{
"seriesname": "reqC",
"data": [{
"value": "129963"
}, {
"value": "261162"
}]
}, {
"seriesname": "resC",
"data": [{
"value": "80522"
}, {
"value": "83743"
}]
}]
}, {
"dataset": [{
"seriesname": "reqC",
"data": [{
"value": "438860"
}]
}, {
"seriesname": "resC",
"data": [{
"value": "166107"
}]
}]
}]

Related

Merge array of an object based on a common field

I have an object that looks like as follows:
[
{
"Net_Amount": 499,
"Date": "2022-01-09T18:30:00.000Z",
"Scheme_Name": "CUSTOMERWINBACKJCA01",
"Month": "Jan"
},
{
"Net_Amount": 902,
"Date": "2022-01-09T18:30:00.000Z",
"Scheme_Name": "CUSTOMERWINBACKJCA02",
"Month": "Jan"
},
{
"Net_Amount": 1860,
"Date": "2022-10-01T18:30:00.000Z",
"Scheme_Name": "CUSTOMERCONNECTJCA",
"Month": "Oct"
},
{
"Net_Amount": 1889,
"Date": "2022-11-01T18:30:00.000Z",
"Scheme_Name": "CUSTOMERCONNECTJCA",
"Month": "Nov"
}
]
Now, if you will look carefully, I have a common field Month in the objects and I want merge the objects based on this common field only. How I want my object to be formatted is as :
[
{
"Month": "Jan",
"varData": [{
"Net_Amount": 499,
"Date": "2022-01-09T18:30:00.000Z",
"Scheme_Name": "CUSTOMERWINBACKJCA01"
},
{
"Net_Amount": 902,
"Date": "2022-01-09T18:30:00.000Z",
"Scheme_Name": "CUSTOMERWINBACKJCA02"
}]
},
{
"Month": "Oct",
"varData": [{
"Net_Amount": 1860,
"Date": "2022-10-01T18:30:00.000Z",
"Scheme_Name": "CUSTOMERCONNECTJCA"
}]
},
{
"Month": "Nov",
"varData": [{
"Net_Amount": 1889,
"Date": "2022-11-01T18:30:00.000Z",
"Scheme_Name": "CUSTOMERCONNECTJCA"
}]
}
]
I can do it by iterating over the array and checking if month is same, then pushing the other key and its value of object in the varData but I want to know if there is any shortcut or inbuilt function which I can use to achieve my purpose.
I don't think that there is some better built-in solution then iterating the array.
But if you use month names as keys then the code could be quite straightforward (the output is not exactly the same but quite similarly structured).
const result = {}
for (const entry of list) {
if (!result[entry.Month]) {
result[entry.Month] = []
}
result[entry.Month].push(entry)
}
See jsfiddle.
If you need the output that is exactly specified in the question then you can use the following code:
let result = {}
for (const entry of list) {
const month = entry.Month
if (!result[month]) {
result[month] = {
"Month": month,
"varData": []
}
}
delete entry.Month
result[month].varData.push(entry)
}
result = Object.values(result)
See jsfiddle
const data = [{"Net_Amount":499,"Date":"2022-01-09T18:30:00.000Z","Scheme_Name":"CUSTOMERWINBACKJCA01","Month":"Jan"},{"Net_Amount":902,"Date":"2022-01-09T18:30:00.000Z","Scheme_Name":"CUSTOMERWINBACKJCA02","Month":"Jan"},{"Net_Amount":1860,"Date":"2022-10-01T18:30:00.000Z","Scheme_Name":"CUSTOMERCONNECTJCA","Month":"Oct"},{"Net_Amount":1889,"Date":"2022-11-01T18:30:00.000Z","Scheme_Name":"CUSTOMERCONNECTJCA","Month":"Nov"}]
console.log([...new Set(data.map(i=>i.Month))].map(Month=>
({Month, varData: data.filter(({Month:m})=>m===Month).map(({Month,...o})=>o)})))
const dataArr = [
{
Net_Amount: 499,
Date: "2022-01-09T18:30:00.000Z",
Scheme_Name: "CUSTOMERWINBACKJCA01",
Month: "Jan",
},
{
Net_Amount: 902,
Date: "2022-01-09T18:30:00.000Z",
Scheme_Name: "CUSTOMERWINBACKJCA02",
Month: "Jan",
},
{
Net_Amount: 1860,
Date: "2022-10-01T18:30:00.000Z",
Scheme_Name: "CUSTOMERCONNECTJCA",
Month: "Oct",
},
{
Net_Amount: 1889,
Date: "2022-11-01T18:30:00.000Z",
Scheme_Name: "CUSTOMERCONNECTJCA",
Month: "Nov",
},
];
const outputObj = dataArr.reduce((acc, crt) => {
acc[crt.Month] ??= [];
acc[crt.Month].push(crt);
return acc;
}, {});
const outputArr = Object.values(outputObj).map((item) => ({ Month: item[0].Month, varData: item }));
console.log(outputArr);

Javascript: rearrage json output in a specific array format

Another dumb moment for me. Spent hours through for loops, maps, reduce, dictionaries but just can't seem to figure it out. I have a json data that look like this
{
"timeline": [
{
"series": "series1",
"data": [
{
"date": "20200713T120000Z",
"value": 0
},
{
"date": "20200714T120000Z",
"value": 8
},
{
"date": "20200715T120000Z",
"value": 0
}
]
},
{
"series": "series2",
"data": [
{
"date": "20200713T120000Z",
"value": 0
},
{
"date": "20200714T120000Z",
"value": 0
}
]
},
{
"series": "series3",
"data": [
{
"date": "20200713T120000Z",
"value": 1
},
{
"date": "20200714T120000Z",
"value": 0
}
]
},
{
"series": "series4",
"data": [
{
"date": "20200713T120000Z",
"value": 2
},
{
"date": "20200714T120000Z",
"value": 4
}
]
}
]
}
I need it in this format
[
{
date: "20200713T120000Z",
series1: 0,
series2: 0,
series3: 1,
series4: 2
},
{
date: "20200714T120000Z",
series1: 8,
series2: 0,
series3: 0,
series4: 4
}
]
Need to do this in JavaScript. Any help/ pointers will be much appreciated.
You could take an object forgrouping and an array for storing all keys for getting an ordered result with all same keys.
This approach filters all zero values from the result set.
const
data = { timeline: [{ series: "series1", data: [{ date: "20200713T120000Z", value: 0 }, { date: "20200714T120000Z", value: 8 }, { date: "20200715T120000Z", value: 0 }] }, { series: "series2", data: [{ date: "20200713T120000Z", value: 0 }, { date: "20200714T120000Z", value: 0 }] }, { series: "series3", data: [{ date: "20200713T120000Z", value: 1 }, { date: "20200714T120000Z", value: 0 }] }, { series: "series4", data: [{ date: "20200713T120000Z", value: 2 }, { date: "20200714T120000Z", value: 4 }] }] },
keys = ['date'],
result = Object
.values(data.timeline.reduce((r, { series, data }) => {
keys.push(series);
data.forEach(({ date, value }) => {
if (!value) return;
if (!r[date]) r[date] = { date };
r[date][series] = value;
});
return r;
}, {}))
.map(o => ({ ...Object.fromEntries(keys.map(k => [k, 0])), ...o }));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This is temporary solution for this, you can try this. I'm using lodash, so please install it.
var _ = require('lodash')
const data = {"timeline": [ { "series": "series1", "data": [ { "date": "20200713T120000Z", "value": 0 },{ "date": "20200714T120000Z", "value": 8 },{ "date": "20200715T120000Z", "value": 0 }] },{ "series": "series2", "data": [ { "date": "20200713T120000Z", "value": 0 },{ "date": "20200714T120000Z", "value": 0 }] },{ "series": "series3", "data": [ { "date": "20200713T120000Z", "value": 1 },{ "date": "20200714T120000Z", "value": 0 }] },{ "series": "series4", "data": [ { "date": "20200713T120000Z", "value": 2 },{ "date": "20200714T120000Z", "value": 4 }] }] }
const t = _.flattenDeep(data.timeline.map(i => i.data.map(d => ({...d, series: i.series}))))
const result = t.reduce((acc, i) => {
const index = acc.findIndex(a => a.date === i.date)
if(index !== -1){
acc[index] = {
...acc[index],
[i.series]: i.value
}
}else {
acc.push({
date: i.date,
[i.series]: i.value
})
}
return acc
}, [])
console.log(result)
Use multiple forEach loops and build an object to track. Then get Object.values
const convert = (arr) => {
const res = {};
arr.forEach(({ series, data }) =>
data.forEach(
({ date, value }) =>
(res[date] = { ...(res[date] ?? { date }), [series]: value })
)
);
return Object.values(res);
};
obj = {"timeline": [ { "series": "series1", "data": [ { "date": "20200713T120000Z", "value": 0 },{ "date": "20200714T120000Z", "value": 8 },{ "date": "20200715T120000Z", "value": 0 }] },{ "series": "series2", "data": [ { "date": "20200713T120000Z", "value": 0 },{ "date": "20200714T120000Z", "value": 0 }] },{ "series": "series3", "data": [ { "date": "20200713T120000Z", "value": 1 },{ "date": "20200714T120000Z", "value": 0 }] },{ "series": "series4", "data": [ { "date": "20200713T120000Z", "value": 2 },{ "date": "20200714T120000Z", "value": 4 }] }] }
const res = convert(obj.timeline);
console.log(res)

How to parse JSON nested in list from bls.gov for use in react-chartjs-2

I'm trying to use the API provided by bls.gov - specifically https://api.bls.gov/publicAPI/v1/timeseries/data/CES0000000001 and break it down into individual variables(?) for use in react-chartjs-2.
I've managed to figure out how to fetch it, and add the raw JSON output to my site. What I am trying to do now is correctly parse the JSON so that it can be added in chart.js.
Here is the code that I used to fetch from the API. Currently it gives a popup alert on the site with the raw JSON from the GET request.
import React, { Component } from 'react'
class Testing extends Component {
getDataUsingGet() {
// Get request
fetch('https://api.bls.gov/publicAPI/v1/timeseries/data/CES0000000001',{
method: 'GET'
// Request type
})
.then((response) => response.json())
// If response is in json then in success
.then((responseJson) => {
//Success
alert(JSON.stringify(responseJson));
const obj = JSON.parse(responseJson);
// ... Code for parsing to go here?
console.log(responseJson)
})
// If response is not in json then throw error
.catch((error) => {
//Error
alert(JSON.stringify(error))
console.error(error)
});
}
render() {
return(
<div>
{/* Render the alert message in browser */}
{ this.getDataUsingGet() }
</div>
);
}
}
export default Testing
This is the format of the JSON from the GET request.
{
"status": "REQUEST_SUCCEEDED",
"responseTime": 177,
"message": [],
"Results": {
"series": [
{
"seriesID": "CES0000000001",
"data": [
{
"year": "2020",
"period": "M03",
"periodName": "March",
"latest": "true",
"value": "151786",
"footnotes": [
{
"code": "P",
"text": "preliminary"
}
]
},
{
"year": "2020",
"period": "M02",
"periodName": "February",
"value": "152487",
"footnotes": [
{
"code": "P",
"text": "preliminary"
}
]
},
...
And finally, this is the code I'm using to generate the chart with react-chartjs-2. It's currently filled with sample data from the example chart.
import React, { Component } from 'react';
import {Bar} from 'react-chartjs-2';
// TESTING FOR FETCHING API FROM WWW.BLS.GOV
// Data input for the RateChart chart.js generation -> 'data'
const data = {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'US Unemployment Rate',
backgroundColor: 'rgba(255,99,132,0.2)',
borderColor: 'rgba(255,99,132,1)',
borderWidth: 1,
hoverBackgroundColor: 'rgba(255,99,132,0.4)',
hoverBorderColor: 'rgba(255,99,132,1)',
data: [65, 59, 80, 81, 56, 55, 40]
}
]
};
const RateChart = () => {
return (
<div>
<h2>Current unemployment</h2>
<Bar
data={data}
width={100}
height={50}
options={{
responsive: true,
maintainAspectRatio: true
}}
/>
</div>
);
}
export default RateChart;
In summary:
How do I take the JSON, break it down into year, periodName, and value so that they can be added to my RateChart component using jsx/javascript?
Thank you
Try something like this to parse that json. You will need to add null catches and such for when you don't get a successfull response, but based on what code you provided this should work.
Also, syntax wise, you should probably only return the response.json, and make the getDataUsingGet function asynchronus, await the fetch call, then handle the response! It is a much cleaner workflow than nesting .thens
class Testing extends Component {
getDataUsingGet() {
// Get request
fetch('https://api.bls.gov/publicAPI/v1/timeseries/data/CES0000000001',{
method: 'GET'
// Request type
})
.then((response) => response.json())
// If response is in json then in success
.then((responseJson) => {
//Success
alert(JSON.stringify(responseJson));
const obj = responseJson;
// ... Code for parsing to go here?
for(var i = 0; i < obj.Results.series.length; i++){
series = obj.Results.series[i];
for(var j = 0; j < series.data.length; j++){
console.log(series.data[j].year)
console.log(series.data[j].period)
}
}
})
// If response is not in json then throw error
.catch((error) => {
//Error
alert(JSON.stringify(error))
console.error(error)
});
}
render() {
return(
<div>
{/* Render the alert message in browser */}
{ this.getDataUsingGet() }
</div>
);
}
}
export default Testing
const obj = {}
axios.get('https://api.bls.gov/publicAPI/v1/timeseries/data/CES0000000001')
.then(function(response){
const res = response.data.Results.series[0].data
res.map(data=>{
obj.period = data.period // same for the rest
})
});
You could do something like:
let result = json.Results.series.map((serie) =>
serie.data.map(({ year, periodName, value }) => ({
year,
periodName,
value,
}))
);
let json = {
status: "REQUEST_SUCCEEDED",
responseTime: 214,
message: [],
Results: {
series: [{
seriesID: "CES0000000001",
data: [{
year: "2020",
period: "M03",
periodName: "March",
latest: "true",
value: "151786",
footnotes: [{
code: "P",
text: "preliminary",
}, ],
},
{
year: "2020",
period: "M02",
periodName: "February",
value: "152487",
footnotes: [{
code: "P",
text: "preliminary",
}, ],
},
{
year: "2020",
period: "M01",
periodName: "January",
value: "152212",
footnotes: [{}],
},
{
year: "2019",
period: "M12",
periodName: "December",
value: "151998",
footnotes: [{}],
},
{
year: "2019",
period: "M11",
periodName: "November",
value: "151814",
footnotes: [{}],
},
{
year: "2019",
period: "M10",
periodName: "October",
value: "151553",
footnotes: [{}],
},
{
year: "2019",
period: "M09",
periodName: "September",
value: "151368",
footnotes: [{}],
},
{
year: "2019",
period: "M08",
periodName: "August",
value: "151160",
footnotes: [{}],
},
{
year: "2019",
period: "M07",
periodName: "July",
value: "150953",
footnotes: [{}],
},
{
year: "2019",
period: "M06",
periodName: "June",
value: "150759",
footnotes: [{}],
},
{
year: "2019",
period: "M05",
periodName: "May",
value: "150577",
footnotes: [{}],
},
{
year: "2019",
period: "M04",
periodName: "April",
value: "150492",
footnotes: [{}],
},
{
year: "2019",
period: "M03",
periodName: "March",
value: "150282",
footnotes: [{}],
},
{
year: "2019",
period: "M02",
periodName: "February",
value: "150135",
footnotes: [{}],
},
{
year: "2019",
period: "M01",
periodName: "January",
value: "150134",
footnotes: [{}],
},
{
year: "2018",
period: "M12",
periodName: "December",
value: "149865",
footnotes: [{}],
},
{
year: "2018",
period: "M11",
periodName: "November",
value: "149683",
footnotes: [{}],
},
{
year: "2018",
period: "M10",
periodName: "October",
value: "149549",
footnotes: [{}],
},
{
year: "2018",
period: "M09",
periodName: "September",
value: "149348",
footnotes: [{}],
},
{
year: "2018",
period: "M08",
periodName: "August",
value: "149268",
footnotes: [{}],
},
{
year: "2018",
period: "M07",
periodName: "July",
value: "149024",
footnotes: [{}],
},
{
year: "2018",
period: "M06",
periodName: "June",
value: "148888",
footnotes: [{}],
},
{
year: "2018",
period: "M05",
periodName: "May",
value: "148669",
footnotes: [{}],
},
{
year: "2018",
period: "M04",
periodName: "April",
value: "148391",
footnotes: [{}],
},
{
year: "2018",
period: "M03",
periodName: "March",
value: "148254",
footnotes: [{}],
},
{
year: "2018",
period: "M02",
periodName: "February",
value: "148078",
footnotes: [{}],
},
{
year: "2018",
period: "M01",
periodName: "January",
value: "147672",
footnotes: [{}],
},
],
}, ],
},
};
let result = json.Results.series.map((serie) =>
serie.data.map(({
year,
periodName,
value
}) => ({
year,
periodName,
value,
}))
);
console.log(result);

How to return and get the sum of object properties based on given filters?

I have the following object.
var data = [
{"Name":"ABC","Dept":"First","FY":"2016","Quarter":"1","Month":"April","Total":"100"},
{"Name":"ABC","Dept":"Second","FY":"2017","Quarter":"2","Month":"May","Total":"200"},
{"Name":"ABC","Dept":"First","FY":"2016","Quarter":"1","Month":"June","Total":"150"},
{"Name":"DEF","Dept":"First","FY":"2016","Quarter":"1","Month":"April","Total":"200"},
{"Name":"DEF","Dept":"Second","FY":"2017","Quarter":"2","Month":"May","Total":"100"},
{"Name":"DEF","Dept":"First","FY":"2016","Quarter":"1","Month":"June","Total":"500"}
]
I want to filter on the abve object to get:
a. I want to return Total based on my filters(ex: If I give Name as ABC, Dept as First, FY as 2016, Quarter as 1, Month as April, then it should filter/return the Total i.e 100 for the given filters)
b. Similarly, I want to return Sum of all the Totals(ex: if I give Name as ABC, Dept as First, FY as 2016 - then it should return sum of the required Total values(i.e 100+150=250) for the given FY 2016 only)
Please help me in this requirement, how can I achieve, Thanks.
I have tried below, but it is giving all the results for given Name(ex: If I give Name as ABC, then it is returning all the details ABC only)
return getData().then(res => {
res.data.filter(customerDetails =>{
if(customerDetails.Name === name && customerDetails.FY === fy && customerDetails.Quarter === quarter && customerDetails.Month === month && customerDetails.Dept === dept)
agent.add(`Details: ${name}, Dept: ${customerDetails.Dept},
FY: ${customerDetails.FY}, Quarter: ${customerDetails.Quarter}, Month: ${customerDetails.Month},
Total: ${customerDetails.Total} `);
});
});
You can use Array.filter() to do that. Filter data based on passed values, and then add Total values of filtered data to get final total.
var data = [{ "Name": "ABC", "Dept": "First", "FY": "2016", "Quarter": "1", "Month": "April", "Total": "100" }, { "Name": "ABC", "Dept": "Second", "FY": "2017", "Quarter": "2", "Month": "May", "Total": "200" }, { "Name": "ABC", "Dept": "First", "FY": "2016", "Quarter": "1", "Month": "June", "Total": "150" }, { "Name": "DEF", "Dept": "First", "FY": "2016", "Quarter": "1", "Month": "April", "Total": "200" }, { "Name": "DEF", "Dept": "Second", "FY": "2017", "Quarter": "2", "Month": "May", "Total": "100" }, { "Name": "DEF", "Dept": "First", "FY": "2016", "Quarter": "1", "Month": "June", "Total": "500" }];
function getTotal(filters) {
var total = 0;
const filteredData = data.filter(item => {
for (var key in filters) {
if (item[key] != filters[key]) {
return false;
}
}
return true;
});
filteredData.forEach(value => total += Number(value.Total));
return total;
}
console.log(getTotal({ "Name": "ABC", "Dept": "First", "FY": "2016" }));
console.log(getTotal({"Name": "DEF" }));
You could take an object with the wanted filter values and filter the array and return the sum of all Total.
function getTotal(data, filters) {
var f = Object.entries(filters);
return data
.filter(o => f.every(([k, v]) => o[k] == v))
.reduce((s, { Total }) => s + +Total, 0);
}
var data = [{ Name: "ABC", Dept: "First", FY: "2016", Quarter: "1", Month: "April", Total: "100" }, { Name: "ABC", Dept: "Second", FY: "2017", Quarter: "2", Month: "May", Total: "200" }, { Name: "ABC", Dept: "First", FY: "2016", Quarter: "1", Month: "June", Total: "150" }, { Name: "DEF", Dept: "First", FY: "2016", Quarter: "1", Month: "April", Total: "200" }, { Name: "DEF", Dept: "Second", FY: "2017", Quarter: "2", Month: "May", Total: "100" }, { Name: "DEF", Dept: "First", FY: "2016", Quarter: "1", Month: "June", Total: "500" }];
console.log(getTotal(data, { Name: 'ABC', Dept: 'First', FY: 2016, Quarter: 1, Month: 'April' })); // 100
console.log(getTotal(data, { Name: 'ABC', Dept: 'First', FY: 2016 })); // 100 + 150 = 250

Merge complex multidimensionnal array

In Javascript, I created a multidimensionnal array, but for another purpose, I need to convert it.
So my array is like this
array [
0 => {
"ulStatic": [
0 => {
"day": "2019-03-30 18:30:00"
"id": "7"
"origin": "intentions"
}
]
"ulDynamic": [
0 => {
"day": "2019-03-30 18:30:00"
"id": "275"
"origin": "obs"
}
]
"ulCreatedDynamic": []
}
1 => {
"ulStatic": [
0 => {
"day": "2019-03-31 09:30:00"
"id": "8"
"origin": "intentions"
}
]
"ulDynamic": []
"ulCreatedDynamic": []
}
2 => {
"ulStatic": []
"ulDynamic": []
"ulCreatedDynamic": [
0 => {
"day": "2019-04-03 19:30:00"
"id": "277"
"origin": "obs"
}
]
}
]
And I'm trying to have this array :
array [
0 => {
"day": "2019-03-30 18:30:00"
"elements": [
0 => {
"id": "7"
"origin": "intentions"
}
1 => {
"id": "275"
"origin": "obs"
}
]
}
1 => {
"day": "2019-03-31 09:30:00"
"elements": [
0 => {
"id": "8"
"origin": "intentions"
}
]
}
2 => {
"day": "2019-04-03 19:30:00"
"elements": [
0 => {
"id": "277"
"origin": "obs"
}
]
}
]
And I must admit that I do not know where to start. I'm looking for map(), splice(), concat(), but it's confusing for me.
Can you help me to give some advices to achieve that ?
Thank you
You could group your data by day by iterating the values of the value of the objects and their array.
var array = [{ ulStatic: [{ day: "2019-03-30 18:30:00", id: "7", origin: "intentions" }], ulDynamic: [{ day: "2019-03-30 18:30:00", id: "275", origin: "obs" }], ulCreatedDynamic: [] }, { ulStatic: [{ day: "2019-03-31 09:30:00", id: "8", origin: "intentions" }], ulDynamic: [], ulCreatedDynamic: [] }, { ulStatic: [], ulDynamic: [], ulCreatedDynamic: [{ day: "2019-04-03 19:30:00", id: "277", origin: "obs" }] }],
result = array.reduce((r, o) => {
Object
.values(o)
.forEach(a => a.forEach(({ day, id, origin }) => {
var temp = r.find(p => day === p.day);
if (!temp) r.push(temp = { day, elements: [] });
temp.elements.push({ id, origin });
}));
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
let originalArr = [{
ulStatic: [
{
day: '2019-03-30 18:30:00',
id: '7',
origin: 'intentions'
}
],
ulDynamic: [
{
day: '2019-03-30 18:30:00',
id: '275',
origin: 'obs'
}
],
ulCreatedDynamic: []},{ulStatic: [
{
day: '2019-03-31 09:30:00',
id: '8',
origin: 'intentions'
}
],
ulDynamic: [],
ulCreatedDynamic: []},{ ulStatic: [],
ulDynamic: [],
ulCreatedDynamic: [
{
day: '2019-04-03 19:30:00',
id: '277',
origin: 'obs'
}
]}];
let op = originalArr.map(item => {
let ulStatic = item.ulStatic.map(ul => {
return {
id: ul.id,
origin: ul.origin
};
});
let ulDynamic = item.ulDynamic.map(ul => {
return {
id: ul.id,
origin: ul.origin
};
});
let ulCreatedDynamic = item.ulCreatedDynamic.map(ul => {
return {
id: ul.id,
origin: ul.origin
};
});
let day;
if (ulStatic.length > 0) {
day = item.ulStatic[0].day;
} else if (ulDynamic.length > 0) {
day = item.ulDynamic[0].day;
} else if (ulCreatedDynamic.length > 0) {
day = item.ulCreatedDynamic[0].day;
}
return {
day: day,
elements: [].concat(ulStatic).concat(ulDynamic)
};
});
console.log(op);
Check this out
grouping the input by day with reduce and return the object values.
const inputAry = [{
"ulStatic": [{
"day": "2019-03-30 18:30:00",
"id": "7",
"origin": "intentions"
}],
"ulDynamic": [{
"day": "2019-03-30 18:30:00",
"id": "275",
"origin": "obs"
}],
"ulCreatedDynamic": []
},
{
"ulStatic": [{
"day": "2019-03-31 09:30:00",
"id": "8",
"origin": "intentions",
}],
"ulDynamic": [],
"ulCreatedDynamic": []
},
{
"ulStatic": [],
"ulDynamic": [],
"ulCreatedDynamic": [{
"day": "2019-04-03 19:30:00",
"id": "277",
"origin": "obs"
}]
}
];
const groupByDay = inputAry.reduce((group, statics) => {
// flattens the statics array
[].concat.apply([], Object.values(statics))
.forEach(({
day,
id,
origin
}) => {
// creates a dictionary entry with day as key, if already exist use the existing one or creates a new entry
group[day] = group[day] || {
day,
elements: []
};
// push the id and origin to elements
group[day].elements.push({
id,
origin
});
});
return group;
}, {});
const expectedResult = Object.values(groupByDay);
console.log(expectedResult);

Categories

Resources