I feel that im close to the answer but I am not outputting exactly the format Im looking for
So, I have this array of objects:
const data = [
{email: '[email protected]', amount: '30', date: '2018-12'},
{email: '[email protected]', amount: '30', date: '2018-11'},
{email: '[email protected]', amount: '30', date: '2018-10'},
{email: '[email protected]', amount: 0, date: '2018-12'},
{email: '[email protected]', amount:'30', date: '2018-11'},
{email: '[email protected]', amount:'30', date: '2018-10'},
{email: '[email protected]', amount:'30', date: '2018-09'},
{email: '[email protected]', amount:'25', date: '2018-08'},
{email: '[email protected]', amount:'25', date: '2018-08'},]
As you can see in the data set there are repeated emails as well as duplicate objects like the last 2 in the data set.
I want to turn it into this array of objects:
const data = [
{
email: '[email protected]',
'2018-12': '30',
'2018-11': '30',
'2018-10': '30',
'2018-09': 0,
'2018-08': 0,
'2018-07': 0,
'2018-06': 0,
'2018-05': 0,
'2018-04': 0,
'2018-03': 0,
'2018-02': 0,
'2018-01': 0,
'2017-12': 0,
},
{
email: '[email protected]',
'2018-12':0,
'2018-11':'30',
'2018-10':'30',
'2018-09':'30',
'2018-08':'25',
'2018-07': 0,
'2018-06': 0,
'2018-05': 0,
'2018-04': 0,
'2018-03': 0,
'2018-02': 0,
'2018-01': 0,
'2017-12': 0,
}]
The output has a range of dates from 2017-12 to 2018-12 and the value for the date key is the amount for that specific date, else if the date is not found on the object the value for that date defaults to 0
At the moment Im playing with the reduce() function using something like this:
let result = data.reduce((acc, {email, date, amount}) => {
acc.email = email
acc[date] = amount
return acc;
}, {});
result is only returning the last email with not exactly the range of dates Im looking for.
Thanks in advance for your help.
Reduce into an object indexed by each email
, creating the inner object explicitly if the [email]
property doesn't exist on the accumulator yet. Once you're sure the object exists, you can assign to acc[email][date]
, and at the end, use Object.values
to transform the object back into the desired array format:
const data = [
{email: '[email protected]', amount: '30', date: '2018-12'},
{email: '[email protected]', amount: '30', date: '2018-11'},
{email: '[email protected]', amount: '30', date: '2018-10'},
{email: '[email protected]', amount: 0, date: '2018-12'},
{email: '[email protected]', amount:'30', date: '2018-11'},
{email: '[email protected]', amount:'30', date: '2018-10'},
{email: '[email protected]', amount:'30', date: '2018-09'},
{email: '[email protected]', amount:'25', date: '2018-08'},
{email: '[email protected]', amount:'25', date: '2018-08'},]
let result = data.reduce((acc, {email, date, amount}) => {
if (!acc[email]) acc[email] = { email };
acc[email][date] = amount;
return acc;
}, {});
console.log(Object.values(result));
const data = [
{email: '[email protected]', amount: '30', date: '2018-12'},
{email: '[email protected]', amount: '30', date: '2018-11'},
{email: '[email protected]', amount: '30', date: '2018-10'},
{email: '[email protected]', amount: 0, date: '2018-12'},
{email: '[email protected]', amount:'30', date: '2018-11'},
{email: '[email protected]', amount:'30', date: '2018-10'},
{email: '[email protected]', amount:'30', date: '2018-09'},
{email: '[email protected]', amount:'25', date: '2018-08'},
{email: '[email protected]', amount:'25', date: '2018-08'},
];
/*
Reduce into an object with email as key and email
and date/amount(s) as value, wrapped in Object.values
to return the array of augmented data values.
*/
augmentData = (data) => Object.values(
data.reduce((acc, {email, amount, date}) => {
(acc[email] || (acc[email] = {email}))[date] = amount;
return acc;
}, {})
);
/*
Reduce straight to array of augmented data
objects containing email and date/amount values.
*/
augmentData2 = data => data.reduce((acc, {email, amount, date}) => {
const findEl = (arr) => arr.find(el => el.email == email);
const createEl = (arr, email) => arr.push({email}) && findEl(arr);
(findEl(acc) || createEl(acc, email))[date] = amount;
return acc;
}, []);
const augmentedData = augmentData(data);
console.log('augmentedData', augmentedData);
const augmentedData2 = augmentData2(data);
console.log('augmentedData2', augmentedData2);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With