How merge two arrays conditional on inner keys? - javascript

I have two arrays which look like below:
array1 = [
{
id: 'A',
values: [
{ date: '1/1/2022', measure: 231 },
{ date: '1/2/2022', measure: 31 },
],
},
{
id: 'B',
values: [
{ date: '1/1/2020', measure: 51 },
{ date: '1/2/2020', measure: 66 },
],
},
];
const array2 = [
{
id: 'AA',
values: [
{ date: '1/1/2022', measure: 23 },
{ date: '1/2/2022', measure: 67 },
],
},
{
id: 'BB',
values: [
{ date: '1/1/2020', measure: 90 },
{ date: '1/2/2020', measure: 100 },
],
},
];
The arrays have unequal ids but it is known key A should be merged with AA, B should be merged with BB and so on. Dates are equal in case of A and AA, B and BB, etc.
I want to merge A and AA (and rest) as below:
arrayFinall = [
{
id: 'A-AA',
values: [
{date:"1/1/2022", measure1: 231, measure2: 23 },
{date: "1/2/2022", measure1: 31, measure2: 67}},
],
{
id: 'B-BB',
values: [
{date:"1/1/2020", measure1: 51, measure1: 90},
{date:"1/2/2020", measure1: 66, measure1: 100},
}
]
Either creating a new array that has both measures and the date for a new key A-AA
or
push measure from array2 into appropriate position in array 1 work in this case.

const array1 = [
{
id: 'A',
values: [
{ date: '1/1/2022', measure: 231 },
{ date: '1/2/2022', measure: 31 },
],
},
{
id: 'B',
values: [
{ date: '1/1/2020', measure: 51 },
{ date: '1/2/2020', measure: 66 },
],
},
];
const array2 = [
{
id: 'AA',
values: [
{ date: '1/1/2022', measure: 23 },
{ date: '1/2/2022', measure: 67 },
],
},
{
id: 'BB',
values: [
{ date: '1/1/2020', measure: 90 },
{ date: '1/2/2020', measure: 100 },
],
},
];
function mergeArrays(array1, array2) {
const result = [];
const keys = Object.keys(array1);
keys.forEach((key) => {
const array1Values = array1[key].values;
const array2Values = array2[key].values;
const values = [];
array1Values.forEach((value) => {
const date = value.date;
const measure1 = value.measure;
const measure2 = array2Values.find((value2) => value2.date === date).measure;
values.push({ date, measure1, measure2 });
});
result.push({ id: `${array1[key].id}-${array2[key].id}`, values });
});
return result;
}
console.log(JSON.stringify(mergeArrays(array1, array2), null, 2));

Related

How can I access this property in my dictionary in js?

I thought I understood how to loop through a dictionary, but my loop is wrong. I try to access the name of each sub item but my code does not work.
Here is what I did:
list = [
{
title: 'Groceries',
items: [
{
id: 4,
title: 'Food',
cost: 540 ,
},
{
id: 5,
title: 'Hygiene',
cost: 235,
},
{
id: 6,
title: 'Other',
cost: 20,
},
],
}];
function calculateCost(){
let total = 0;
Object.keys(list).forEach((k) => { for (i in k.items) { total += i.data; } });
console.log(total);
return total;
}
Your list is an array includes 1 object and this object has two properties title and items the items here is an array of objects each one of these objects has property cost so to calculate the total cost you need to loop through items array, here is how you do it:
let list = [
{
title: 'Groceries',
items: [
{
id: 4,
title: 'Food',
cost: 540 ,
},
{
id: 5,
title: 'Hygiene',
cost: 235,
},
{
id: 6,
title: 'Other',
cost: 20,
},
],
}];
function calculateCost(){
let total = 0;
list[0].items.forEach(el => {
total += el.cost;
})
console.log(total)
return total;
}
calculateCost();
Your list is an Array, not an Object.
Instead of Object.keys() use Array.prototype.reduce:
const calculateCost = (arr) => arr.reduce((tot, ob) =>
ob.items.reduce((sum, item) => sum + item.cost, tot), 0);
const list = [
{
title: 'Groceries',
items: [
{id: 4, title: 'Food', cost: 10},
{id: 5, title: 'Hygiene', cost: 20},
{id: 6, title: 'Other', cost: 30}
]
}, {
title: 'Other',
items: [
{id: 8, title: 'Scuba gear', cost: 39}
],
}
];
console.log(calculateCost(list)); // 99
Expanding on #Roko's and #mmh4all's answers, the following code adds several verification statements to handle cases where a deeply nested property in your data is not what you expect it to be.
const calculateCost = (orders) => {
let listOfCosts = [];
// For each 'order' object in the 'orders' array,
// add the value of the 'cost' property of each item
// in the order to 'listOfCosts' array.
orders.forEach(order => {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
if (!Array.isArray(order.items)) { return; }
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseFloat
const orderCostArr = order.items.map(item =>
isNaN(item.cost) ? 0 : parseFloat(item.cost, 10));
if (orderCostArr.length === 0) { return; }
// Concatenate 'orderCostArr' to the 'listOfCosts' array
//listOfCosts = listOfCosts.concat(orderCostArry);
// Alternate approach is to use the spread syntax (...) to
// push the items in the array returned by 'order.items.map()'
// into the 'listOfCosts' array.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
listOfCosts.push(...orderCostArr);
});
// Use the 'reduce' method on the 'listOfCosts' array
// to get the total cost.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
const totalCost = listOfCosts.reduce(
(accumulator, currentValue) => accumulator + currentValue, 0);
return totalCost;
};
const list = [
{
title: 'Groceries',
items: [
{ id: 4, title: 'Food', cost: 10 },
{ id: 3, title: 'Baked goods', cost: 20 },
{ id: 5, title: 'Hygiene', cost: 0 },
{ id: 6, title: 'Other' }
]
}, {
title: 'Gear',
items: {},
}, {
title: 'Accessories',
items: [],
}, {
title: 'Bags',
}, {
title: 'Other',
items: [
{ id: 10, title: 'Scuba gear', cost: "5" },
{ id: 8, title: 'Scuba gear', cost: "err" },
{ id: 9, title: 'Scuba gear', cost: 59 }
],
}
];
console.log(calculateCost(list)); // 94

How to Group JavaScript Array of Object based on key

So I have a data like this
const carts = [
{
name: 'Voucher A',
participants: [
{
date: 112
},
{
date: 112
}
],
supplierName: 'ABC',
ticketDescription: 'Description of',
...data
},
{
name: 'Voucher B',
participants: [
{
date: 111
},
{
date: 112
}
],
supplierName: 'ABC',
ticketDescription: 'Description of',
...data
}
]
And I want to group it based on the date (if it has same date). So for data above, the expected result will be
expected = [
{
name: 'Voucher A',
date: 1,
count: 1,
supplierName: 'ABC',
ticketDescription: 'Description of',
...data
},
{
name: 'Voucher A',
date: 2,
count: 1,
supplierName: 'ABC',
ticketDescription: 'Description of',
...data
}
]
Because it has different date. But if it has same date, the expected result will be
expected = [
{
name: 'Voucher A',
date: 1,
count: 2,
supplierName: 'ABC',
ticketDescription: 'Description of',
...data
}
]
I was trying to use reduce to group it but it did not give the structure I want
carts.forEach(cart => {
cart.participants.reduce((acc, obj) => {
acc[obj.date] = [...acc[obj.date] || [], obj]
return acc
}, {})
})
To organize the data, I think you need two associations to group by: the name and the dates and their counts for that name:
const carts = [
{
name: 'Voucher A',
participants: [
{
date: 1
},
{
date: 2
}
]
}
];
const groupedByNames = {};
for (const { name, participants } of carts) {
if (!groupedByNames[name]) groupedByNames[name] = {};
for (const { date } of participants) {
groupedByNames[name][date] = (groupedByNames[name][date] || 0) + 1;
}
}
const output = Object.entries(groupedByNames).flatMap(
([name, dateCounts]) => Object.entries(dateCounts).map(
([date, count]) => ({ name, date: Number(date), count })
)
);
console.log(output);
If you want use, just plain for loops, you can try this solution. It looks simple and elegant 😜😜
const carts = [
{
name: 'Voucher A',
participants: [
{
date: 1
},
{
date: 1
},
{
date: 2
}
]
},
{
name: 'Voucher B',
participants: [
{
date: 1
},
{
date: 2
},
{
date: 2
}
]
}
]
const finalOutput = []
for (const cart of carts) {
for (const participant of cart.participants) {
const res = finalOutput.find(e => e.name === cart.name && e.date === participant.date)
if (res) {
res.count += 1
} else {
finalOutput.push({ name: cart.name, date: participant.date, count: 1 })
}
}
}
console.log(finalOutput)
Use forEach and destructuring
const process = ({ participants, name }) => {
const res = {};
participants.forEach(({ date }) => {
res[date] ??= { name, count: 0, date };
res[date].count += 1;
});
return Object.values(res);
};
const carts = [
{
name: "Voucher A",
participants: [
{
date: 1,
},
{
date: 2,
},
],
},
];
console.log(carts.flatMap(process));
const carts2 = [
{
name: "Voucher A",
participants: [
{
date: 1,
},
{
date: 1,
},
],
},
];
console.log(carts2.flatMap(process));

Pushing data from this array to another uses the least loop

I want to config data from 'data2' array to 'dataConvert' array
and I want to find another way of optimizing.
let dataConvert = [];
data2 = [
{
time: "2020-7",
tasks: [
{
key: "p1",
value: 15
},
{
key: "p2",
value: 13
},
]
},
{
time: "2020-8",
tasks: [
{
key: "p1",
value: 16
},
{
key: "p2",
value: 19
},
]
},
{
time: "2020-9",
tasks: [
{
key: "p1",
value: 12
},
{
key: "p2",
value: 93
},
]
}
]
After adding data to the 'dataConvert' array, then 'dataConvert' is formatted as follows:
dataConvert = [
["x","2020-7", "2020-8", "2020-9"],
["p1", 15, 16, 12],
["p2", 13, 19, 93]
]
i tried use reduce , I want to find another way of optimizing.
let dateConvert = [], valueConvert = [];
data2.forEach(x=>{
let date = new Date(x.time);
if (date) {
let getYear = date.getFullYear();
let getMonth = date.getMonth() + 1;
let newDate = `${getYear}-${getMonth}-1`;
return dateConvert = [...dateConvert, newDate];
}
})
dateConvert.unshift("x");
// get p1 p2 value
let allTasks = data2.flatMap(x => x.tasks);
valueConvert = Object.values(allTasks.reduce((arr, item) => {
arr[item.key] = arr[item.key] || [item.key];
arr[item.key].push(item.value);
return arr;
}, {}));
dataConvert = [...[dateConvert], ...valueConvert];
thank u.
You could take nested loops and store the index in an object for faster access of key.
const
data = [{ time: "2020-7", tasks: [{ key: "p1", value: 15 }, { key: "p2", value: 13 }] }, { time: "2020-8", tasks: [{ key: "p1", value: 16 }, { key: "p2", value: 19 }] }, { time: "2020-9", tasks: [{ key: "p1", value: 12 }, { key: "p2",value: 93 }] }],
dataConvert = [['x']],
indices = {};
data.forEach(o => {
dataConvert[0].push(o.time);
o.tasks.forEach(({ key, value }) => {
if (!(key in indices)) indices[key] = dataConvert.push([key]) - 1;
dataConvert[indices[key]].push(value);
});
});
console.log(dataConvert);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comparing Two Arrays and Grouping into Inserts and Updates

I am comparing two arrays and then grouping them into inserts and updates. The updates array should end up including elements that match on id == Id, but where open_balance !- DocumentAmount. The inserts array should include only elements where the id != Id. Notice I am running both through the toString() method because in my scenario one is of type String whereas the other is of type Integer from two different SQL Databases.
Now, with the code I have now, the first grouping works - via the findRecordsToUpdate() function, I get all of the elements matched correctly for the updates - which should be two elements, because these two match on id, but not on the amount:
recordsToUpdate: [
{ Id: '333', DocumentAmount: 20 },
{ Id: '444', DocumentAmount: 10 }
]
But the inserts, which is produced by the findRecordsToInsert() function, are not correct. According to my data I should end up with one element, with an Id of '555' in my recordsToUpdate array, because it's the only element with an Id not found in the other array -- i.e. it's a new record to insert. But instead I end up with 13 elements with my current code?
What am I missing here and what do I need to change to get the correct inserts populated to my recordsToInsert array?:
const sourceArr = [
{ id: 111, open_balance: 10 },
{ id: 222, open_balance: 20 },
{ id: 333, open_balance: 10 },
{ id: 444, open_balance: 20 },
]
const targetArr = [
{ Id: '111', DocumentAmount: 10 },
{ Id: '222', DocumentAmount: 20 },
{ Id: '333', DocumentAmount: 20 },
{ Id: '444', DocumentAmount: 10 },
{ Id: '555', DocumentAmount: 10 },
]
function findRecordsToUpdate () {
if (sourceArr.length && targetArr.length) {
let recordsToUpdate = [];
for (let t of targetArr) {
for (let s of sourceArr) {
if ((t.Id.toString() == s.id.toString()) && (t.DocumentAmount != s.open_balance)) {
recordsToUpdate.push(t);
}
}
}
console.log('recordsToUpdate: ', recordsToUpdate);
return recordsToUpdate;
}
};
function findRecordsToInsert () {
if (sourceArr.length && targetArr.length) {
let recordsToInsert = [];
for (let t of targetArr) {
for (let s of sourceArr) {
if (t.Id.toString() != s.id.toString()) {
recordsToInsert.push(t);
}
}
}
console.log('recordsToInsert: ', recordsToInsert);
return recordsToInsert;
}
};
findRecordsToUpdate();
findRecordsToInsert();
By the way, to clarify, my findRecordsToInsert() function should return a recordsToInsert array like this when done, as the record with an Id of 555 is the only record from the second array that doesn't exist in the first array:
recordsToInsert: [{ Id: '555', DocumentAmount: 10 }]
So, to be clear, it's just the findRecordsToInsert() function that is not working correctly at present.
Use a combination of Array#filter and Array#find to get your insert and update arrays out of targetArr.
'use strict';
const sourceArr = [
{ id: 111, open_balance: 10 },
{ id: 222, open_balance: 20 },
{ id: 333, open_balance: 10 },
{ id: 444, open_balance: 20 },
];
const targetArr = [
{ Id: '111', DocumentAmount: 10 },
{ Id: '222', DocumentAmount: 20 },
{ Id: '333', DocumentAmount: 20 },
{ Id: '444', DocumentAmount: 10 },
{ Id: '555', DocumentAmount: 10 },
];
// Target records with a matching source (on ID) where the amount has changed.
// Update these.
const recordsToUpdate = targetArr
.filter(tar => sourceArr
.find(source => source.id === Number(tar.Id) && source.open_balance !== tar.DocumentAmount));
console.log(recordsToUpdate);
// Target records that have no matching source record (i.e. new records).
// Insert these.
const recordsToInsert = targetArr
.filter(tar => !sourceArr
.find(source => source.id === Number(tar.Id)));
console.log(recordsToInsert);
Edit
Just for the record, in your original code the search in findRecordsToInsert is incorrect. To fix the issue, try to find each target in source and, if not found, add target to the insert array. But it's just a long-winded version of filter-find.
const sourceArr = [
{ id: 111, open_balance: 10 },
{ id: 222, open_balance: 20 },
{ id: 333, open_balance: 10 },
{ id: 444, open_balance: 20 },
]
const targetArr = [
{ Id: '111', DocumentAmount: 10 },
{ Id: '222', DocumentAmount: 20 },
{ Id: '333', DocumentAmount: 20 },
{ Id: '444', DocumentAmount: 10 },
{ Id: '555', DocumentAmount: 10 },
]
function findRecordsToInsert () {
if (sourceArr.length && targetArr.length) {
const recordsToInsert = [];
for (const t of targetArr) {
let found = false;
for (let i = 0; i < sourceArr.length && !found; ++i) {
if (t.Id.toString() === sourceArr[i].id.toString())
found = true;
}
if (!found)
recordsToInsert.push(t);
}
console.log('recordsToInsert: ', recordsToInsert);
return recordsToInsert;
}
};
findRecordsToInsert();
You could take a hash table and just filter the target array.
const
sourceArr = [{ id: 111, open_balance: 10 }, { id: 222, open_balance: 20 }, { id: 333, open_balance: 10 }, { id: 444, open_balance: 20 }],
targetArr = [{ Id: '111', DocumentAmount: 10 }, { Id: '222', DocumentAmount: 20 }, { Id: '333', DocumentAmount: 20 }, { Id: '444', DocumentAmount: 10 }, { Id: '555', DocumentAmount: 10 }],
source = sourceArr.reduce((r, { id, open_balance }) => (r[id] = open_balance, r), {}),
recordsToUpdate = targetArr.filter(({ Id, DocumentAmount }) =>
Id in source && source[Id] !== DocumentAmount),
recordsToInsert = targetArr.filter(({ Id }) => !(Id in source));
console.log(recordsToUpdate);
console.log(recordsToInsert);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Efficiently pull unknown data, separate, and store in specific format?

I've got data I need to sort through, filter, and store in a specific way. I'll explain by showing. Here is the data:
var pieData, cakeData, icecreamData;
var desserts = [
{
pies: [
{
name: "blueberry",
count: 3
},
{
name: "pumpkin",
count: 6
},
{
name: "apple",
count: 9
}
],
cakes: [
{
name: "chocolate",
count: 3
},
{
name: "foam",
count: 6
},
{
name: "wedding",
count: 9
}
],
icecream: [
{
name: "chocolate",
count: 3
},
{
name: "strawberry",
count: 6
},
{
name: "mint-chip",
count: 9
}
],
date: "2016-01-06T00:00:00"
},
{
pies: [
{
name: "blueberry",
count: 2
},
{
name: "pumpkin",
count: 4
},
{
name: "apple",
count: 6
}
],
cakes: [
{
name: "chocolate",
count: 2
},
{
name: "foam",
count: 4
},
{
name: "wedding",
count: 6
}
],
icecream: [
{
name: "chocolate",
count: 2
},
{
name: "strawberry",
count: 4
},
{
name: "mint-chip",
count: 6
}
],
date: "2016-01-07T00:00:00"
},
{
pies: [
{
name: "blueberry",
count: 4
},
{
name: "pumpkin",
count: 8
},
{
name: "apple",
count: 12
}
],
cakes: [
{
name: "chocolate",
count: 4
},
{
name: "foam",
count: 8
},
{
name: "wedding",
count: 12
}
],
icecream: [
{
name: "chocolate",
count: 4
},
{
name: "strawberry",
count: 8
},
{
name: "mint-chip",
count: 12
}
],
date: "2016-01-08T00:00:00"
}
];
So I've got my data. The data is basically what types of pies, cakes, and icereams there are which can vary in number, name, and count. Each object in desserts is a day, with the date as the last property. I'll go straight to what I want to get out of it and then explain further after that. Here is what I need to get out of it:
pieData = [
{
name: "blueberry",
dates: ["2016-01-06T00:00:00", "2016-01-07T00:00:00", "2016-01-08T00:00:00"],
counts: [3, 2, 4]
},
{
name: "pumpkin",
dates: ["2016-01-06T00:00:00", "2016-01-07T00:00:00", "2016-01-08T00:00:00"],
counts: [6, 4, 8]
},
{
name: "apple",
dates: ["2016-01-06T00:00:00", "2016-01-07T00:00:00", "2016-01-08T00:00:00"],
counts: [9, 6, 12]
}
];
cakeData = [
{
name: "chocolate",
dates: ["2016-01-06T00:00:00", "2016-01-07T00:00:00", "2016-01-08T00:00:00"],
counts: [3, 2, 4]
},
{
name: "foam",
dates: ["2016-01-06T00:00:00", "2016-01-07T00:00:00", "2016-01-08T00:00:00"],
counts: [6, 4, 8]
},
{
name: "wedding",
dates: ["2016-01-06T00:00:00", "2016-01-07T00:00:00", "2016-01-08T00:00:00"],
counts: [9, 6, 12]
}
];
icecreamData = [
{
name: "chocolate",
dates: ["2016-01-06T00:00:00", "2016-01-07T00:00:00", "2016-01-08T00:00:00"],
counts: [3, 2, 4]
},
{
name: "strawberry",
dates: ["2016-01-06T00:00:00", "2016-01-07T00:00:00", "2016-01-08T00:00:00"],
counts: [6, 4, 8]
},
{
name: "mint-chip",
dates: ["2016-01-06T00:00:00", "2016-01-07T00:00:00", "2016-01-08T00:00:00"],
counts: [9, 6, 12]
}
];
So I need to pass the desserts variable to a function and have it set the pieData, cakeData, and icecreamData variables, declared at the top of the original data, to the array of objects I've shown in the second bit of code.
A Few Things to Note:
In the output data, the values correspond to the days they were originally assigned in the original data. For example, pieData[0].dates[0] corresponds to pieData[0].counts[0] as it appears in the original data.
There could be infinite types of each dessert or none. Meaning there could be 10 different objects in the "pie" array in the original data or none. But there will always be pies, cakes, and icecream arrays, whether they are empty or have a thousand objects in them.
I don't know what types of each dessert will come through. It could be anything. So the pie could be named "pumpkin" or it could be named "battery acid".
My only solution I could think of was to do multiple loops and nested loops and just overall too much code. I know there has to be some efficient wizardry to get this done right.
I understand the drive to want "minified" code, but I think it's best to keep things readable. Despite your reservations, I think a few nested loops make sense in this case.
Consider the following way of getting the desired result:
var pieData, cakeData, icecreamData;
var desserts = [{pies:[{name:"blueberry",count:3},{name:"pumpkin",count:6},{name:"apple",count:9}],cakes:[{name:"chocolate",count:3},{name:"foam",count:6},{name:"wedding",count:9}],icecream:[{name:"chocolate",count:3},{name:"strawberry",count:6},{name:"mint-chip",count:9}],date:"2016-01-06T00:00:00"},{pies:[{name:"blueberry",count:2},{name:"pumpkin",count:4},{name:"apple",count:6}],cakes:[{name:"chocolate",count:2},{name:"foam",count:4},{name:"wedding",count:6}],icecream:[{name:"chocolate",count:2},{name:"strawberry",count:4},{name:"mint-chip",count:6}],date:"2016-01-07T00:00:00"},{pies:[{name:"blueberry",count:4},{name:"pumpkin",count:8},{name:"apple",count:12}],cakes:[{name:"chocolate",count:4},{name:"foam",count:8},{name:"wedding",count:12}],icecream:[{name:"chocolate",count:4},{name:"strawberry",count:8},{name:"mint-chip",count:12}],date:"2016-01-08T00:00:00"}];
var dessertData= {};
for (var dessertGroup of desserts) {
for (var item in dessertGroup) {
// the timestamp is not a dessert, so skip it
if (item === 'date') { continue; }
if (!dessertData[item]) {
// this is a new kind of dessert, add it
dessertData[item] = [];
}
for (var flavour of dessertGroup[item]) {
// get the index of the flavour
var index = dessertData[item].map(function(e) { return e.name; }).indexOf(flavour.name);
if (index < 0) {
// this is a new flavour of dessert, add it to the dessert type
dessertData[item].push({
name: flavour.name,
dates: [],
counts: []
});
index = dessertData[item].length - 1;
}
// append the relevant data to the flavour properties
dessertData[item][index].dates.push(dessertGroup.date);
dessertData[item][index].counts.push(flavour.count);
}
}
}
// finally, we want 'cakes' in 'cakeData'
// 'pies' in 'pieData'
// and 'icecream in 'icecreamData'
cakeData = dessertData.cakes;
pieData = dessertData.pies;
icecreamData = dessertData.icecream;
console.log("cakeData=", cakeData);
console.log("pieData=", pieData);
console.log("icecreamData=", icecreamData);
This is easy to read and modify. Also, it allows for any type of dessert! Why limit yourself to pies, cake, and icecream.
You'll notice that I'm dynamically creating and accessing the properties of dessertData by doing stuff like dessertData[propertyName].
Maybe you knew that was possible, but I used javascript for a long time before learning that the [] syntax wasn't just for numerical indices. Good luck!
This converts it into the format you want
https://jsfiddle.net/sdhjL7dv/
var pieData = [], cakeData = [], icecreamData = [];
var desserts = [
{
pies: [
{
name: "blueberry",
count: 3
},
{
name: "pumpkin",
count: 6
},
{
name: "apple",
count: 9
}
],
cakes: [
{
name: "chocolate",
count: 3
},
{
name: "foam",
count: 6
},
{
name: "wedding",
count: 9
}
],
icecream: [
{
name: "chocolate",
count: 3
},
{
name: "strawberry",
count: 6
},
{
name: "mint-chip",
count: 9
}
],
date: "2016-01-06T00:00:00"
},
{
pies: [
{
name: "blueberry",
count: 2
},
{
name: "pumpkin",
count: 4
},
{
name: "apple",
count: 6
}
],
cakes: [
{
name: "chocolate",
count: 2
},
{
name: "foam",
count: 4
},
{
name: "wedding",
count: 6
}
],
icecream: [
{
name: "chocolate",
count: 2
},
{
name: "strawberry",
count: 4
},
{
name: "mint-chip",
count: 6
}
],
date: "2016-01-07T00:00:00"
},
{
pies: [
{
name: "blueberry",
count: 4
},
{
name: "pumpkin",
count: 8
},
{
name: "apple",
count: 12
}
],
cakes: [
{
name: "chocolate",
count: 4
},
{
name: "foam",
count: 8
},
{
name: "wedding",
count: 12
}
],
icecream: [
{
name: "chocolate",
count: 4
},
{
name: "strawberry",
count: 8
},
{
name: "mint-chip",
count: 12
}
],
date: "2016-01-08T00:00:00"
}
];
for(var i = 0; i < desserts.length; i++) {
var d = desserts[i].date;
desserts[i].pies.length && save(pieData, desserts[i].pies, d);
desserts[i].cakes.length && save(cakeData, desserts[i].cakes, d);
desserts[i].icecream.length && save(icecreamData, desserts[i].icecream, d);
}
function save(destination, items, d) {
for(var i = 0; i < items.length; i++) {
var name = items[i].name;
var count = items[i].count;
if(destination[name] === undefined) { destination[name] = {name:'',dates:[],counts:[]}; }
destination[name].name = name;
destination[name].dates.push(d);
destination[name].counts.push(count);
}
}
console.log(pieData);
console.log(cakeData);
console.log(icecreamData);

Categories

Resources