I am trying to loop through the array of objects below to get the data value in this format:
Market_Name, District_Name, State, Commodity, Variety, datetimes, Price
{
"Market_Name":{
"0":"A lot",
"1":"A lot",
"2":"A lot",
"3":"A lot",
"4":"A lot",
"5":"A lot"
},
"District_Name":{
"0":"Ratlam",
"1":"Ratlam",
"2":"Ratlam",
"3":"Ratlam",
"4":"Ratlam",
"5":"Ratlam"
},
"State":{
"0":"AP",
"1":"AP",
"2":"AP",
"3":"AP",
"4":"AP",
"5":"AP"
},
"Commodity":{
"0":"Wheat",
"1":"Wheat",
"2":"Wheat",
"3":"Wheat",
"4":"Wheat",
"5":"Wheat"
},
"Variety":{
"0":"Medium",
"1":"Medium",
"2":"Medium",
"3":"Medium",
"4":"Medium",
"5":"Medium"
},
"datetimes":{
"0":"2020-01-01",
"1":"2020-01-02",
"2":"2020-01-03",
"3":"2020-01-04",
"4":"2020-01-05",
"5":"2020-01-06"
},
"Price":{
"0":"1981",
"1":"1970",
"2":"1981",
"3":"1970",
"4":"1968",
"5":"1974"
}
}
I have done some scripting but none seems get the desired result of what I want. Can anyone assist on how to solve this?
CodePudding user response:
You don't have an array; you have an object. You should use Object.entries
, at which point you can simply reduce
.
You haven't given your exact target shape, but I can only assume it's something like this.
const data = {
"Market_Name": {
"0":"A lot", "1":"A lot", "2":"A lot",
"3":"A lot", "4":"A lot", "5":"A lot",
},
"District_Name":{
"0":"Ratlam", "1":"Ratlam", "2":"Ratlam",
"3":"Ratlam", "4":"Ratlam", "5":"Ratlam",
},
"State":{
"0":"AP", "1":"AP", "2":"AP",
"3":"AP", "4":"AP", "5":"AP",
},
"Commodity":{
"0":"Wheat", "1":"Wheat", "2":"Wheat",
"3":"Wheat", "4":"Wheat", "5":"Wheat"
},
"Variety":{
"0":"Medium", "1":"Medium", "2":"Medium",
"3":"Medium", "4":"Medium", "5":"Medium",
},
"datetimes":{
"0":"2020-01-01", "1":"2020-01-02", "2":"2020-01-03",
"3":"2020-01-04", "4":"2020-01-05", "5":"2020-01-06",
},
"Price":{
"0":"1981", "1":"1970", "2":"1981",
"3":"1970", "4":"1968", "5":"1974",
},
};
const transformed = Object.values(Object.entries(data)
.reduce((acc, [ key, value ]) => {
Object.values(value).forEach((data, i) => {
if (!acc[i]) acc[i] = { };
acc[i][key] = data;
});
return acc;
}, { }));
console.log(transformed);
This builds an object that looks like
{
"0": { /* [market_name][0], [district_name][0] */ },
"1": { /* [market_name][1], [district_name][1] */ },
/* and so on... */
"n": { /* [field_name_1][n], [field_name_n][n] */ }
}
and then uses Object.values
to get an array out of it. Using an Object for a middle step allows us to add things at arbitary indexes before reducing it back down to an array.
Here is the same thing, writtin with classic for
-loops instead of .reduce
. It will perhaps be a little easier to follow.
CodePudding user response:
You can clean up code by creating index/name for rows and cols. Find number of rows and the name of columns. And traverse the data.
const combine = (obj) => {
const cols = Object.keys(obj);
const rows = Object.keys(obj["Market_Name"]);
return rows.map((rowId) =>
cols.reduce((m, colId) => {
m[colId] = obj[colId][rowId];
return m;
}, {})
);
};
//Simple version
const combine2 = (obj) => {
const cols = Object.keys(obj);
//take first col keys as rows count
const noOfRows = Object.keys(obj[cols[0]]).length;
let rows = [];
for (let rowId = 0; rowId < noOfRows; rowId ) {
let row = {};
for (let col of cols) {
row[col] = obj[col][rowId];
}
rows.push(row);
}
return rows;
};
const data = {
Market_Name: {
0: "A lot",
1: "A lot",
2: "A lot",
3: "A lot",
4: "A lot",
5: "A lot",
},
District_Name: {
0: "Ratlam",
1: "Ratlam",
2: "Ratlam",
3: "Ratlam",
4: "Ratlam",
5: "Ratlam",
},
State: {
0: "AP",
1: "AP",
2: "AP",
3: "AP",
4: "AP",
5: "AP",
},
Commodity: {
0: "Wheat",
1: "Wheat",
2: "Wheat",
3: "Wheat",
4: "Wheat",
5: "Wheat",
},
Variety: {
0: "Medium",
1: "Medium",
2: "Medium",
3: "Medium",
4: "Medium",
5: "Medium",
},
datetimes: {
0: "2020-01-01",
1: "2020-01-02",
2: "2020-01-03",
3: "2020-01-04",
4: "2020-01-05",
5: "2020-01-06",
},
Price: {
0: "1981",
1: "1970",
2: "1981",
3: "1970",
4: "1968",
5: "1974",
},
};
console.log(combine(data));
console.log(combine2(data));