Mapping object to array in js - javascript

I am beginner in data structure and trying to improve my skills.
I am trying to divide the object value to list of other object.
So I/P is
1st Object JSON:
let mapMonth ={
"10": 8,
"11": 30,
"12": 31,
"01": 23
}
where 10 is Oct, 11 is Nov, 12 is Dec and 01 is Jan.
2nd Object JSON:
let mapData = {
"key1": {
"subkey1": [
[407341537, 1666737463, 363248139, 596560162]
],
"subkey2": ["Oct", "Nov", "Dec", "Jan"]
},
"key2": {
"subkey1": [
[78491802, 334718068, 68299710, 81365082]
],
"subkey2": ["Oct", "Nov", "Dec", "Jan"]
},
"key3": {
"subkey1": [
[501844, 3362217, 648527, 1073573]
],
"subkey2": ["Oct", "Nov", "Dec", "Jan"]
}
}
So now I need to divide 407341537 with 8 i.e 50917692.125, 1666737463 with 30 i.e 55557915.4333 and so on..
Expected output:
{
"key1": {
"subkey1": [
[50917692.125, 55557915.4333, 11717681.9,72466846.2174]
],
"subkey2": ["Oct", "Nov", "Dec", "Jan"]
},
"key2": {
"subkey1": [
[9811475.25, 11157268.9333, 2203216.45161, 3537612.26087]
],
"subkey2": ["Oct", "Nov", "Dec", "Jan"]
},
"key3": {
"subkey1": [
[62730.5, 112073.9, 20920.225, 46677.086]
],
"subkey2": ["Oct", "Nov", "Dec", "Jan"]
}
}
Code I have tried:
let averageObj = {};
var count = 0;
for (let key in mapData) {
averageObj[key] = [];
mapData[key]['subkey1'][0].forEach((data, index) => {
for (let monthKey in mapMonth) {
averageObj[key].push(data / mapMonth[monthKey]);
}
});
}
Please let me know if you need anything else.

Assuming an object with fixed keys and nested array with only one index:
This approach mutates the original object.
let mapMonthDesc = {"Oct": "10","Nov": "11","Dec": "12","Jan": "01"},
mapMonth = {"10": 8,"11": 30,"12": 31,"01": 23},
mapData = {"key1": {"subkey1": [[407341537, 1666737463, 363248139, 596560162]],"subkey2": ["Oct", "Nov", "Dec", "Jan"]},"key2": {"subkey1": [[78491802, 334718068, 68299710, 81365082]],"subkey2": ["Oct", "Nov", "Dec", "Jan"]},"key3": {"subkey1": [[501844, 3362217, 648527, 1073573]],"subkey2": ["Oct", "Nov", "Dec", "Jan"]}};
Object.values(mapData).forEach(({subkey1: [numbers], subkey2}) => {
numbers.forEach((n, i) => numbers[i] = n / mapMonth[mapMonthDesc[subkey2[i]]]);
});
console.log(mapData);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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);

JS group by month/year of date

I have an array with date and id's I want to convert it group by month and by year year
oldest date/month should be at first
let myArray = [
{project_id: 444, date: "2021-08-17 14:33:49"},
{project_id: 444, date: "2021-08-16 14:33:50"},
{project_id: 555, date: "2020-08-16 14:33:50"},
{project_id: 666, date: "2020-08-17 12:33:50"},
{project_id: 666, date: "2020-09-17 12:33:50"},
{project_id: 666, date: "2020-09-17 12:33:50"},
];
The below array is my actual requirement that is manually converted from the above array
eg:
[
{
"month_year": "Aug 2020",
"data": [
{
"date": "2020-08-16 14:33:50",
"project_id": 666
},
{
"date": "2020-08-17 12:33:50",
"project_id": 777
}
]
},
{
"month_year": "Sep 2020",
"data": [
{
"date": "22020-09-17 12:33:50",
"project_id": 666
},
{
"date": "2020-09-17 12:33:50",
"project_id": 666
}
]
},
{
"month_year": "Aug 2021",
"data": [
{
"date": "2021-08-17 14:33:49",
"project_id": 444
},
{
"date": "2021-08-16 14:33:50",
"project_id": 444
}
]
},
]
Something like this should work:
function groupByDate(list) {
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
let result = [];
for (let obj of list) {
let objDate = new Date(obj.date);
let monthYear = `${monthNames[objDate.getMonth()]} ${objDate.getFullYear()}`;
let foundMatch = false;
for (let i = 0; i < result.length; i++) {
if (result[i].month_year === monthYear) {
result[i].data.push(obj);
foundMatch = true;
break;
}
}
if (!foundMatch) {
result.push({
"month_year": monthYear,
"data": [obj]
});
}
}
return result;
}
Basically it loops over each object in the list, and if the current date (month and year only) hasn't already been processed, it will add another json object to the result list. If the current date have been processed before, it adds it to the correct json.
Working JSFiddle:
https://jsfiddle.net/dfhg41sx/1/

how could i change the string data format ..?

The data format, which I get from back-end is
{
"2020-08-22": 1425,
"2020-08-23": 1475,
"2020-08-24": 1475,
"flightnumber": "EK-853",
"source": "emirates",
"stops": "stops-0"
}
Is that possible to change the key data as following
{
"Aug 22": 1425,
"Aug 23": 1475,
"Aug 24": 1475,
"flightnumber": "EK-853",
"source": "emirates",
"stops": "stops-0"
}
Please tell me some solution for this.
Below snippet could help you. It has several things to notice:
iterate through object's keys
object's dynamic key
detect invalid date
const data = {
"2020-08-22": 1425,
"2020-08-23": 1475,
"2020-08-24": 1475,
flightnumber: "EK-853",
source: "emirates",
stops: "stops-0",
}
const monthNames = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
]
const res = {}
Object.keys(data).forEach((k) => {
const date = new Date(k)
if (!isNaN(date.getTime())) {
res[`${monthNames[date.getMonth()]} ${date.getDate()}`] = data[k]
} else {
res[k] = data[k]
}
})
console.log(res)

Get data from nested array of objects which are not present in another nested array of objects

I have the following arrs:
data:[
{
"servicename": "Income Tax Return Filling",
"serviceid": 10,
"clients": [
{
"serviceid": 10,
"periodicity": "H",
"clientnos": [
"A2222"
]
},
{
"serviceid": 10,
"periodicity": "M",
"clientnos": [
"B0002",
"B3064",
"CI0155"
]
},
{
"serviceid": 10,
"periodicity": "Q",
"clientnos": [
"C0166"
]
},
{
"serviceid": 10,
"periodicity": "Y",
"clientnos": [
"C0023",
"C001"
]
}
]
},
{
"servicename": "GSTR 3B",
"serviceid": 17,
"clients": [
{
"serviceid": 17,
"periodicity": "M",
"clientnos": [
"C0008",
"C0004",
"C0023",
"C001"
]
},
{
"serviceid": 17,
"periodicity": "Y",
"clientnos": [
"C0001",
"C0005",
"C0190"
]
}
]
},
]
and
"result": [
[
{
"clientnos": [
"B0002",
"B3064",
"CI0155"
],
"compperiod": "Mar",
"serviceid": 10
}
],
[
{
"clientnos": [
"C0004"
],
"compperiod": "Mar",
"serviceid": 17
},
{
"clientnos": [
"C0023",
"C0004",
"C001"
],
"compperiod": "May",
"serviceid": 17
}
],
]
and a monthArr = ['Feb','Mar','Apr','May'] and value of periodicity as priodicity= 'M'. And each month in the monthArr is referred as compperiod.
I want the following output.
output:[
[
{
"clientnos": [],
"compperiod": "Mar",
"serviceid": 10
},
{
"clientnos": [
"B0002",
"B3064",
"CI0155"
],
"compperiod": "Feb",
"serviceid": 10
},
{
"clientnos": [
"B0002",
"B3064",
"CI0155"
],
"compperiod": "Apr",
"serviceid": 10
},
{
"clientnos": [
"B0002",
"B3064",
"CI0155"
],
"compperiod": "May",
"serviceid": 10
}
],
[
{
"clientnos": [
"C0008",
"C0023",
"C001"
],
"compperiod": "Mar",
"serviceid": 17
},
{
"clientnos": [
"C0008"
],
"compperiod": "May",
"serviceid": 17
},
{
"clientnos": [
"C0008",
"C0004",
"C0023",
"C001"
],
"compperiod": "Feb",
"serviceid": 17
},
{
"clientnos": [
"C0008",
"C0004",
"C0023",
"C001"
],
"compperiod": "Apr",
"serviceid": 17
}
],
]
So what's happening in the above data is for each month in the monthArr, I want to show those clientnos in the output which are not present in the result arr.
For ex:
In data arr for service name: 'Income Tax return filling' the clients array consists of clientnos based on different peridocity i.e 'H','M','Y'. I have set the periodicity = 'M'. So now I have to get the clientnos from clients array where perodicity = 'M' for each service in the data array where a clients array object with periodicity='M' exists.
After that in the results arr the sub array gets generate after an sql query. Here I have directly posted the data from the query.
Now I want the following operations to take place to get the output.
The output array consists of data based on the result arr.
For ex: Let's take
result[2] = [
{
"clientnos": [
"C0004"
],
"compperiod": "Mar",
"serviceid": 17
},
{
"clientnos": [
"C0023",
"C0004",
"C001"
],
"compperiod": "May",
"serviceid": 17
}
]
So now in the output data for service id 17 I want to get those clientnos which are not present for each month in the monthArr
i.e In the data arr for serviceid 17 and periodicity 'M' we have the following clientnos = ["C0008", "C0004", "C0023", "C001"]. Now in the result[2] for serviceid 17 and month Mar we have only "C0004" in the clientnos arr, so in the output it should show ["C0008", "C0023", "C001"] in the clientnos arr for serviceid 17 and month Mar.
Now for the month of Feb, there is no data in result[2]. So now we have to show clientnos ["C0008", "C0004", "C0023", "C001"] i.e all clientnos for the month of feb in the output. Same we have to do it with muliple services in the data arr and for each month in the monthArr.
I have tried the following way.
var result = []
for (const element of listService) {
for (const period of element.clients) {
if (periodicity == period.periodicity) {
//Sql query to get sub array present in the result arr.
// i.e if I execute this query for service id 17 I get result[2]
periodArr.forEach(p => {
const r = _.filter(data, { compperiod: p });
if (r[0]) {
const index = data.findIndex(obj => obj.compperiod == r[0].compperiod);
data[index] = {
"clientnos": period.clientnos.filter(e => !r[0].clientnos.includes(e)),
"compperiod": p,
"serviceid": element.serviceid
}
} else {
data.push({
"clientnos": period.clientnos,
"compperiod": p,
"serviceid": element.serviceid
})
}
});
result.push(data);
}
}
};
I have achieved the output in the above way. But is there a way where I can achieve this in an more optimized way. If yes, then how?

creating different dataset array

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"
}]
}]
}]

Categories

Resources