Converting an object to an array - javascript

I tried by using Object.keys() to convert the object
var obj1={
"jan": {
"COAL": "25"
},
"feb": {
"ROM": "50",
"WASTE": "55"
},
"april": {
"COAL": "60"
}
}
to
var obj2=[
{
"month": "jan",
"product": "COAL",
"quantity": "25"
},
{
"month": "feb",
"product": "ROM",
"quantity": "50"
},
{
"month": "feb",
"product": "WASTE",
"quantity": "55"
},
{
"month": "april",
"product": "COAL",
"quantity": "60"
}
]
but failed in the middle as I'm not able to calculate the properties say for example in "feb" there are two products "ROM" and "WASTE", but this can go upto 3 or 4. Can anyone please suggest possible solution for this problem?

This will do:
var res = []
for(i in obj1){
var rowObj = obj1[i];
for(j in rowObj){
var newObj = {'month' : i, 'product' : j, 'quantity' : rowObj[j]}
res.push(newObj);
}
}
console.log(res);

You need to loop over the keys in the outer object, then the keys in the inner objects, so as long as you can depend on ES5 Array methods:
var obj1={
"jan": {
"COAL": "25"
},
"feb": {
"ROM": "50",
"WASTE": "55"
},
"april": {
"COAL": "60"
}
}
var o = Object.keys(obj1).reduce(function(acc, month, i) {
Object.keys(obj1[month]).forEach(function(product) {
acc.push({'month':month, 'product':product, 'quantity':obj1[month][product]})
});
return acc;
}, []);
document.write(JSON.stringify(o));
Using ES6 arrow functions it becomes a little more concise:
var o = Object.keys(obj1).reduce((acc, m) => {
Object.keys(obj1[m]).forEach(p => acc.push({'month':m, 'product':p, 'quantity':obj1[m][p]}));
return acc;
}, []);

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

Is there a way to compare dates and store them in an array?

I'm currently working on a website where Objects are sorted. The Objects are from a database where it's stored with a date (2022-10-13 02:07:11). Is there a way to compare dates and store the ones that are created on the same date? For example: If there are two objects that were created on 2022-10-13, but with at a different time, I would like to save these in an array with the name of the date.
I can't change how it's saved because it's not my DB.
I hope you understand how I mean it.
(I don't know how you want it or how your database is exactly so you might have to change some things)
Try using (something like) this:
let sorted = {};
// replace "data" below with your key
for(key in data){
if(!sorted[data[key].date]){
sorted[data[key].date] = [];
}
sorted[data[key].date].push({key: data[key]});
}
Example in my case:
let data = {
"a": {
"date": "2022-10-13 02:07:11"
},
"b": {
"date": "2022-10-13 00:00:00"
},
"c": {
"date": "2022-10-10 02:07:11"
}
};
let sorted = {};
for (key in data) {
if (!sorted[data[key].date]) {
sorted[data[key].date] = [];
}
sorted[data[key].date].push({
key: data[key]
});
}
console.log(sorted);
A reduce is useful here
Give us more details of the object to give a more tailored answer
const obj = [
{ "id": "a1", "date": "2022-10-13 01:07:11" },
{ "id": "a2", "date": "2022-10-13 02:07:11" },
{ "id": "a3", "date": "2022-10-13 03:07:11" },
{ "id": "b", "date": "2022-10-14 02:07:11" },
{ "id": "c1", "date": "2022-10-15 01:07:11" },
{ "id": "c2", "date": "2022-10-15 02:07:11" },
{ "id": "c3", "date": "2022-10-15 03:07:11" },
{ "id": "d", "date": "2022-10-16 01:07:11" }
];
const grouped = obj.reduce((acc,cur) => {
const key = cur.date.split(" ")[0];
(acc[key] = acc[key] || []).push(cur);
return acc;
},{})
console.log(grouped);

How to groupBy an attribute inside the second array with javascript

I am trying to convert an array object to a new set of arrays grouped by their value. In this case, it is the date value.
What I have tried in in the below code, but I didn't get the results of what I wanted. Can you please help me find the right solution for this problem?
INPUT
let array = [
{
"category": {
"code": "1558950145861"},
"lines": [
{
"date": "2020-02-26",
"price": 9260,
"dispo": 5
},
{
"date": "2020-02-29",
"price": 6300,
"dispo": 9
},
{
"date": "2020-04-01",
"price": 7700,
"dispo": 23
}
]
},
{
"category": {
"code": "1788858954441"
},
"lines": [
{
"date": "2020-02-26",
"price": 6260,
"dispo": 2
},
{
"date": "2020-02-29",
"price": 5500,
"dispo": 4
},
{
"date": "2020-04-01",
"price": 840,
"dispo": 7
}
]
}
];
Desired OUTPUT
[{
"date": "2020-02-26",
"lines": [{
"price": 9260,
"dispo": 5
}, {
"price": 6260,
"dispo": 2
}]
}, {
"date": "2020-02-29",
"lines": [{
"price": 6300,
"dispo": 9
}, {
"price": 5500,
"dispo": 4
}]
}, {
"date": "2020-04-01",
"lines": [{
"price": 7700,
"dispo": 23
}, {
"price": 840,
"dispo": 7
}]
}]
code that I wrote
var result = (_array)
.groupBy(x => {
for (let j = 0; j < x.lines.length; j += 1) {
return x.lines[j].date;
}
})
.map((value, key) => ({
date: key,
lines: value
})).value();
I want my code to generate the desired output, but it isn't doing that. What might I be doing wrong?
try this
let array = [{ "category": { "code": "1558950145861" }, "lines": [{ "date": "2020-02-26", "price": 9260, "dispo": 5 }, { "date": "2020-02-29", "price": 6300, "dispo": 9 }, { "date": "2020-04-01", "price": 7700, "dispo": 23 }] }, { "category": { "code": "1788858954441" }, "lines": [{ "date": "2020-02-26", "price": 6260, "dispo": 2 }, { "date": "2020-02-29", "price": 5500, "dispo": 4 }, { "date": "2020-04-01", "price": 840, "dispo": 7 }] }]
const groupBy = (arr) => arr.reduce((acc, ele)=>( (acc[ele.date] = acc[ele.date] || []).push(ele), acc),{})
const all = [].concat(...array.map(ele=> ele.lines))
const format = ele => ele.map(({price, dispo})=>({price, dispo}))
console.log(Object.entries(groupBy(all)).map(([date, lines])=> ({date, lines: format(lines)})))
Try something like this :
var out = {}
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array[i]["lines"].length; j++) {
let e = array[i]["lines"][j];
if (!out[e["date"]]) {
out[e["date"]] = [];
}
out[e["date"]].push({"price": e["price"], "dispo": e["dispo"]});
}
}
var result = [];
for (let k in out) {
result.push({"date": k, "lines": out[k]});
}
The result variable has the desired output format.
You don't appear to need the category value, so first I'd merge the lines into a single array where you can groupBy from there:
// using your input called 'array'
// First collect just the line arrays:
var arrayOfLineArrays=array.map(category => category.lines);
// Merge them into one bigger array:
var allLines = _.flatten(arrayOfLineArrays);
// Now you can groupBy with ease:
var dateGroupsObject = _(allLines).groupBy(line => line.date);
// And map to an array:
var result = _.values(_.mapObject(dateGroupsObject, (value, key) => ({
date: key,
lines: value
}))));

How to get the sum of children values of an object in a Javascript react native?

Here is my object:
var obj = {
"idtransact1": {
"amount": 3000,
},
"idtransact2": {
"amount": 3000,
}
}
I am trying to get the sum of all amount.
I tried to adapt this example but since it is not the same data structure then i am a bit lost.
var array = [{
"adults": 2,
"children": 3
}, {
"adults": 2,
"children": 1
}];
var val = array.reduce(function(previousValue, currentValue) {
return {
adults: previousValue.adults + currentValue.adults,
children: previousValue.children + currentValue.children
}
});
console.log(val);
Any help would be appreciated.
You can use Object.values() and .reduce() to get the sum:
const data = {
"idtransact1": { "amount": 3000 },
"idtransact2": { "amount": 3000 }
};
const result = Object.values(data).reduce((r, { amount }) => r + amount, 0);
console.log(result);
Using forEach loop
var obj = {
"idtransact1": {
"amount": 3000,
},
"idtransact2": {
"amount": 3000,
}
}
var sum=0;
Object.values(obj).forEach((x)=>sum+=x.amount)
console.log(sum)
A for in loop is your friend when it comes to looking for values in an object.
var obj = {
"idtransact1": {"amount": 3000},
"idtransact2": {"amount": 3000}};
var sumAmount = 0;
for(var char in obj){
sumAmount += obj[char].amount;
}
console.log(sumAmount);
For your second example, the for in loop works the same way with the array of objects.
var array = [
{"adults": 2,"children": 3},
{"adults": 2,"children": 1}];
var sumAdults = 0;
var sumChildren = 0;
for(var char in array){
sumAdults += array[char].adults;
sumChildren += array[char].children;
}
console.log(sumAdults + " " + sumChildren);
Less to remember if you can look for data in objects and data in an array of objects the same way. Enjoy
Array [
Object {
"product": Object {
"cat_id": "20",
"cat_name": "Pizza",
"detail": "Pizza sauce, Green pepper & mozarella cheese",
"discount_price": "",
"has_extra": "0",
"has_variation": "1",
"id": "46",
"image": "chicken-tikka-piza-recipe-main-photo.jpg",
"name": "Chicken Fajita",
"prep_time": "30",
"price": "310",
"status": "1",
"time_stamp": "2021-01-02 19:43:41",
"ven_id": "6",
},
"quantity": 1,
},
Object {
"product": Object {
"cat_id": "20",
"cat_name": "Pizza",
"detail": "Pizza Sauce, Tomato Green Paper, Olives Mashrooms And Chipotle Sauce with extra Creamy mayoneese",
"discount_price": "",
"has_extra": "0",
"has_variation": "0",
"id": "45",
"image": "chicken-tikka-piza-recipe-main-photo.jpg",
"name": "Chicken Tikka",
"prep_time": "15",
"price": "310",
"status": "1",
"time_stamp": "2021-01-02 19:41:56",
"ven_id": "6",
},
"quantity": 3,
},
]
How to calculate its total price where quantity is not the same also I want to calculate total price

d3js roll up a nested JSON array and sum up a total value

I have this JSON
[{
"month": "september",
"detail": [{
"date": "01-09",
"value": 5
}, {
"date": "02-09",
"value": 5
}, {
"date": "03-09",
"value": 5
}, {
"date": "04-09",
"value": 5
}, {
"date": "05-09",
"value": 5
}, {
"date": "06-09",
"value": 5
}, {
"date": "07-09",
"value": 0
}]
},
{
"month": "october",
"detail": [{
"date": "01-10",
"value": 10
}, {
"date": "02-10",
"value": 5
}, {
"date": "03-10",
"value": 5
}, {
"date": "04-10",
"value": 5
}, {
"date": "05-10",
"value": 5
}, {
"date": "07-10",
"value": 10
}]
}
I want to roll up the all the "value" in the object "detail" for each specific month using d3nest. If you count all the values for each specific months it would result in: september-value: 30 & october-value: 40.
I've tried nesting it but I can't get it right to sum up the values for each month. see my code.
d3.json('runningdata.json', function (error, data) {
console.log(data);
var Total = d3.nest()
.key(function(d) { return d.month; })
.rollup(function(value) { return d3.sum(value, function(v) { return v.detail.value; }); })
.entries(data);
console.log(JSON.stringify(Total));
});
All of this above would result in:
[{"key":"september","values":0},{"key":"october","values":0}]
You can notice the "key" are working right, they have the month as value. but the "Values" field result in 0. what i am trying to achieve needs to be:
[{"key":"september","values":30},{"key":"october","values":40}]
But when i try this:
.rollup(function(value) { return d3.sum(value, function(v) { return v.detail[0].value; }); })
instead of:
.rollup(function(value) { return d3.sum(value, function(v) { return v.detail.value; }); })
it shows me the values of the first object in the arrays.
[{"key":"september","values":5},{"key":"october","values":10}]
What am i doing wrong? I have been reading about d3 nesting.
Any help is welcome.
Note:
Im trying achieve this to make a graph which presents the total of each months and when you click on the specific month it will view the details of its month in days.
You have to update your d3.sum function like so:
d3.sum(value[0].detail, function(v) {
return v.value;
});
So your whole code would be:
var Total = d3.nest()
.key(function(d) {
return d.month;
})
.rollup(function(value) {
return d3.sum(value[0].detail, function(v) {
return v.value;
});
})
.entries(data);
You can just use basic javascript .reduce() function to do the trick. This will roll up your array of object structure into a single object with the months as the property name and the sum of the values as the value. The advantage to doing it this way is that if you want to get, say, the total for the month of September, you can simply say combined.september, rather than having to iterate through an array, searching for the object with the key property equal to "september" and then extracting the value. However, if you need to keep your original structure, see the slightly modified version at the bottom of my answer.
var data = [{
"month": "september",
"detail": [{
"date": "01-09",
"value": 5
}, {
"date": "02-09",
"value": 5
}, {
"date": "03-09",
"value": 5
}, {
"date": "04-09",
"value": 5
}, {
"date": "05-09",
"value": 5
}, {
"date": "06-09",
"value": 5
}, {
"date": "07-09",
"value": 0
}]
},
{
"month": "october",
"detail": [{
"date": "01-10",
"value": 10
}, {
"date": "02-10",
"value": 5
}, {
"date": "03-10",
"value": 5
}, {
"date": "04-10",
"value": 5
}, {
"date": "05-10",
"value": 5
}, {
"date": "07-10",
"value": 10
}]
}];
var combined = data.reduce(function (total, current){
total[current.month] = current.detail.reduce(function(tot, curr) {
return tot + curr.value;
}, 0);
return total;
}, {});
console.log(combined);
Edit -- if you need to keep your original {"key": "..", "values", ".."} structure
You can use .map() rather than .reduce() like so:
var combined = data.map(function (elem){
var total = elem.detail.reduce(function(total, current) {
return total + current.value;
}, 0);
return {key: elem.month, values: total};
});
console.log(combined);
// output:
// [ { key: 'september', value: 30 },
// { key: 'october', value: 40 } ]

Categories

Resources