NodeJS: Get Count By Month-Year - javascript

I have some transactional data which looks as below:
[{UserId: 19156, createdAt: "2014-03-01T18:30:00.000Z", …},
{UserId: 19150, createdAt: "2014-03-09T18:30:00.000Z", …},
{UserId: 18459, createdAt: "2014-04-09T18:30:00.000Z", …},
{UserId: 19666, createdAt: "2014-10-24T07:12:05.000Z", …}]
My requirement it to get count by month-year, so that the output looks like below:
[{period: '2014-03', count:2}
{period: '2014-04', count:1},
{period: '2014-10', count:1}]
I'm doing this in Nodejs, and am just not able to work with the date to make this happen.
Can you please help?

You can use the code given below to group based on period year and month.
let array = [{ UserId: 19156, createdAt: "2014-03-01T18:30:00.000Z" },
{ UserId: 19150, createdAt: "2014-03-09T18:30:00.000Z" },
{ UserId: 18459, createdAt: "2014-04-09T18:30:00.000Z" },
{ UserId: 19666, createdAt: "2014-10-24T07:12:05.000Z" }]
function count(array) {
return array.reduce((total, elem) => {
let temp = elem.createdAt.split("-")
let groupKey = temp[0] + "-" + temp[1];
total[groupKey] ? total[groupKey] +=1: total[groupKey] = 1;
// total[groupKey] += 1;
return total
}, {})
}
console.log(count(array))
The output of code above will be
{ '2014-03': 2, '2014-04': 1, '2014-10': 1 }
Of course you can easily convert from JSON format to array format using code given below
function convertToArray(json_data) {
let result = [];
for (var i in json_data)
result.push({ period: i, count: json_data[i] });
return result;
}
The output will be
[ { period: '2014-03', count: 2 },
{ period: '2014-04', count: 1 },
{ period: '2014-10', count: 1 } ]

You can take the substring of date , take the unique and count the frequency of each date
const arr = [{UserId: 19156, createdAt: "2014-03-01T18:30:00.000Z",},
{UserId: 19150, createdAt: "2014-03-09T18:30:00.000Z"},
{UserId: 18459, createdAt: "2014-04-09T18:30:00.000Z"},
{UserId: 19666, createdAt: "2014-10-24T07:12:05.000Z"}]
//take substring and just grab unique date
let distict_dates = [...new Set(arr.map(a => a.createdAt.substring(0, 7)))];
//count each date frequency
let reduced = distict_dates.map(a => {
return {
userCount: arr.filter(a1 => a1.createdAt.startsWith(a)).length,
createdAt: a
}
}
)
console.log(reduced);

You need this method basically:
.reduce((acc = {}, i) => {
let period = i.createdAt.slice(0,7);
acc[period] = {period, count: acc[period] ? acc[period].count+1: 1}
return acc;
}, {})
let t = [{UserId: 19156, createdAt: "2014-03-01T18:30:00.000Z"},
{UserId: 19150, createdAt: "2014-03-09T18:30:00.000Z"},
{UserId: 18459, createdAt: "2014-04-09T18:30:00.000Z"},
{UserId: 19666, createdAt: "2014-10-24T07:12:05.000Z"}].reduce((acc = {}, i) => {
let period = i.createdAt.slice(0,7);
acc[period] = {period, count: acc[period] ? acc[period].count+1: 1}
return acc;
}, {})
console.log(t);
// if you need exact same result then do it like this
console.log(Object.values(t));

using aggregation:
db.collectionName.aggregate([
{
$project:{
period:{$dateToString:{format:"%Y-%m",date:"$createdAt"}}
}
},{
$group:{ _id : {period : "$period"},count:{$sum:1}}
},
{ $sort : { _id : 1 } }
]);

You can try this:
db.doc.aggregate([{ $group: {
_id:null,
period: {
$dateToString: { format: "%Y-%m", date: "$createdAt" } },
count: { $sum: 1 } },
]
).then()

If the createdAt is a string, convert string to date as follows
var t = Date.parse("2015-04-01T18:30:00.000Z");
var date = new Date(d)
Now get the year and month as follows
date.getMonth() // zero indexed
date.getFullYear()
Append them and form your required string format for createdAt

Related

How to filter date between 2 field in array node js

Here is my array object
let getPeriod = [
{
deleted: false,
_id: 6051ae1437daba27db4a9bf4,
period: 'P1',
dateStart: '2020-12-28',
dateEnd: '2021-01-24',
createdAt: 2021-03-17T07:21:56.497Z,
updatedAt: 2021-03-17T07:25:07.382Z,
__v: 0
},
{
deleted: false,
_id: 6052d717e141450e696eea97,
period: 'P3',
dateStart: '2020-02-22',
dateEnd: '2021-03-21',
createdAt: 2021-03-18T04:29:11.885Z,
updatedAt: 2021-03-18T04:29:11.885Z,
__v: 0
},
{
deleted: false,
_id: 605aade7c7a70069e429d3d2,
period: 'P4',
dateStart: '2020-03-22',
dateEnd: '2021-04-18',
createdAt: 2021-03-24T03:11:35.962Z,
updatedAt: 2021-03-24T03:11:35.962Z,
__v: 0
}
]
I want to use moment to get today date and use in filter with period is in this time
const today = moment().format("YYYY-MM-DD");
//2021-03-29
this is what I try to do
getPeriod = getPeriod.filter(
(item) => item.dateStart >= today && item.dateEnd <= today
);
but it's return in [] not use why because It suppose to return preiod: P4 object
UPDATE
Now I use this
getPeriod = getPeriod.filter((item) => {
console.log(moment(item.dateStart), moment(item.dateEnd), today);
moment(item.dateStart).isSameOrAfter(today) &&
moment(item.dateEnd).isSameOrBefore(today);
});
and in console log I got this
Moment<2020-12-28T00:00:00+07:00> Moment<2021-01-24T00:00:00+07:00> Moment<2021-03-29T12:45:21+07:00>
Moment<2020-02-22T00:00:00+07:00> Moment<2021-03-21T00:00:00+07:00> Moment<2021-03-29T12:45:21+07:00>
Moment<2020-03-22T00:00:00+07:00> Moment<2021-04-18T00:00:00+07:00> Moment<2021-03-29T12:45:21+07:00>
still not sure why it still return null data
UPDATE2
I add return in still get null
getPeriod = getPeriod.filter((item) => {
if (
moment(item.dateStart).isSameOrAfter(today) &&
moment(item.dateEnd).isSameOrBefore(today)
) {
return item;
}
});
You can use moment until to create filter condition:
const today = moment(); // Keep today is a moment object
getPeriod = getPeriod.filter(
(item) => moment(item.dateEnd).isSameOrAfter(today) && moment(item.dateStart).isSameOrBefore(today);
);
Ref: document
Update:
Because you want to it returns period: 'P4', then I updated the condition.
If you want use momentjs to compare dates, then your dates should be created using momentjs.
getPeriod = getPeriod.filter(
(item) => (moment(item.dateStart) <= today && moment(item.dateEnd) >= today)
);

How to get regular interval count

So I have the data in below format
const data = [
{ date: '01-07-2019' },
{ date: '02-07-2019' },
{ date: '03-07-2019' },
{ date: '04-07-2019' },
{ date: '05-07-2019' },
{ date: '06-07-2019' },
{ date: '07-07-2019' },
{ date: '08-07-2019' },
{ date: '09-07-2019' },
{ date: '10-07-2019' },
{ date: '15-07-2019' },
{ date: '16-07-2019' },
{ date: '20-07-2019' },
{ date: '21-07-2019' },
{ date: '22-07-2019' },
{ date: '23-07-2019' }
]
So I have to count the regular interval dates. For example on date { date: '10-07-2019' }, { date: '20-07-2019' } and on { date: '23-07-2019' } it breaks so count should be again started with 1.
const ouput = [{
startDate: '01-07-2019',
endDate: '10-07-2019',
count: 10
}, {
startDate: '15-07-2019',
endDate: '16-07-2019',
count: 2
}, {
startDate: '20-07-2019',
endDate: '23-07-2019',
count: 4
}]
I did that
const output = Object.values(data.reduce((a, { startDate, endDate }, i) => {
const startTime = moment(data[i].date)
const endTime = moment(data[i + 1] && data[i + 1].date)
if (moment.duration(endTime.diff(startTime)).asDays === 1) {
a.startDate = startDate
a.startDate = endDate
}
a.count++;
return a;
}, {}));
But it is not giving what I expect. Please help.
I would do that with a function generator to handle the desired aggregation.
The below code will loop the dates, take a pair, check whether the start date exists, update the end date and automatically yield the value if necessary.
Comments are directly in the code below, the code assumes the initial array is already sorted as the example you mentioned.
As a side note, you're actually including the last date in the count, while, effectively, it should be one day less than your count. Further comments about that are available below in the function generator code.
const data = [
{ date: '01-07-2019' },
{ date: '02-07-2019' },
{ date: '03-07-2019' },
{ date: '04-07-2019' },
{ date: '05-07-2019' },
{ date: '06-07-2019' },
{ date: '07-07-2019' },
{ date: '08-07-2019' },
{ date: '09-07-2019' },
{ date: '10-07-2019' },
{ date: '15-07-2019' },
{ date: '16-07-2019' },
{ date: '20-07-2019' },
{ date: '21-07-2019' },
{ date: '22-07-2019' },
{ date: '23-07-2019' }
];
// Counts intervals of consecutive dates.
function* countIntervals(dates) {
// declare an initial accumulator.
let acc = {
count: 0
};
for (let i = 0; i < dates.length; i++) {
// get the currently looped value and the next one.
const [curr, next] = [moment(dates[i].date, 'DD-MM-YYYY'), dates[i+1] ? moment(dates[i+1].date, 'DD-MM-YYYY') : null];
// if the current date and next days are valid and if the difference in days between them is 1..
if (curr && next && (next.diff(curr, "days") === 1)) {
// Then keep track of the start date if not set, update the end date and increase the count of days.
acc.startDate = acc.startDate || dates[i].date, acc.endDate = dates[i+1].date, acc.count++;
}
else {
// otherwise, if the accumulator has a start date, yield the value.
if (acc && acc.startDate) {
acc.count++; // <-- comment this if you don't want the last date to be included.
yield Object.assign({}, acc);
// and init again the accumulator.
acc = {
count: 0
};
}
}
}
// if the loop is finished and the progression continued, yield the current accumulator.
if (acc.startDate) yield acc;
}
// usage...
const intervals = [...countIntervals(data)];
console.log(intervals);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
Here you go, Try this
const data = [
{ date: "01-07-2019" },
{ date: "02-07-2019" },
{ date: "03-07-2019" },
{ date: "04-07-2019" },
{ date: "05-07-2019" },
{ date: "06-07-2019" },
{ date: "07-07-2019" },
{ date: "08-07-2019" },
{ date: "09-07-2019" },
{ date: "10-07-2019" },
{ date: "15-07-2019" },
{ date: "16-07-2019" },
{ date: "20-07-2019" },
{ date: "21-07-2019" },
{ date: "22-07-2019" },
{ date: "23-07-2019" }
];
function to parse date
function parseDate(input) {
var parts = input.split("-");
// new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[2], parts[1] - 1, parts[0]); // Note: months are 0-based
}
function to get date difference
function dateDiff(date1, date2) {
date1 = parseDate(date1);
date2 = parseDate(date2);
let diffTime = Math.abs(date2.getTime() - date1.getTime());
let diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return diffDays;
}
Required output
const output = data.reduce(function(resultSet, currentValue, currentIndex, arr) {
if (resultSet.length == 0) {
resultSet.push({
startDate: currentValue.date,
endDate: currentValue.date,
count: 1
});
}
else{
let dateDiffrence = dateDiff(resultSet[resultSet.length-1].endDate, currentValue.date);
console.log(dateDiffrence);
if(dateDiffrence == 1){
resultSet[resultSet.length-1].endDate = currentValue.date;
resultSet[resultSet.length-1].count++;
}else{
resultSet.push({
startDate: currentValue.date,
endDate: currentValue.date,
count: 1
});
}
}
return resultSet;
}, []);
Yet another possible solution.
const parseDate = (str) => {
const [d, m, y] = str.split('-');
return +new Date(y, m - 1, d)
}
const output = data.reduce((a, {
date
}, i) => {
const cur = parseDate(date);
const lastDate = data[i - 1] && data[i - 1].date || date;
const last = parseDate(lastDate || date);
if (cur - last > 1000 * 60 * 60 * 24) a.push({count: 0});
const {
startDate = date,
count
} = a.pop();
a.push({
startDate,
endDate: date,
count: count + 1
})
return a;
}, [{
count: 0
}])
console.log (output)
<script>
const data = [
{ date: '01-07-2019' },
{ date: '02-07-2019' },
{ date: '03-07-2019' },
{ date: '04-07-2019' },
{ date: '05-07-2019' },
{ date: '06-07-2019' },
{ date: '07-07-2019' },
{ date: '08-07-2019' },
{ date: '09-07-2019' },
{ date: '10-07-2019' },
{ date: '15-07-2019' },
{ date: '16-07-2019' },
{ date: '20-07-2019' },
{ date: '21-07-2019' },
{ date: '22-07-2019' },
{ date: '23-07-2019' }
]</script>
If you construct UTC dates there will be no need to use moment.js. With UTC every day is 24 hours and DST does not apply. This solution features a boilerplate function to handle the creation of the UTC date from your date string format.
const data = [
{ date: '01-07-2019' },
{ date: '02-07-2019' },
{ date: '03-07-2019' },
{ date: '04-07-2019' },
{ date: '05-07-2019' },
{ date: '06-07-2019' },
{ date: '07-07-2019' },
{ date: '08-07-2019' },
{ date: '09-07-2019' },
{ date: '10-07-2019' },
{ date: '15-07-2019' },
{ date: '16-07-2019' },
{ date: '20-07-2019' },
{ date: '21-07-2019' },
{ date: '22-07-2019' },
{ date: '23-07-2019' }
];
const ONE_DAY = 1000 * 60 * 60 * 24;
function dateStrToUTC(dateStr) {
const dateParts = dateStr.split('-');
const utcDate = new Date();
utcDate.setUTCFullYear(dateParts[2]);
utcDate.setUTCMonth(dateParts[1] - 1);
utcDate.setUTCDate(dateParts[0]);
utcDate.setUTCHours(0);
utcDate.setUTCMinutes(0);
utcDate.setUTCSeconds(0);
utcDate.setUTCMilliseconds(0);
return utcDate;
}
function getRegularIntervals(accumulator, currentValue) {
const index = accumulator.length - 1;
let daysPassed = 0;
if (index > -1) {
daysPassed = (dateStrToUTC(currentValue.date) - dateStrToUTC(accumulator[index].endDate)) / ONE_DAY;
}
if (index > -1 && 1 == daysPassed) {
accumulator[index].endDate = currentValue.date;
accumulator[index].count++;
} else {
accumulator.push({
startDate: currentValue.date,
endDate: currentValue.date,
count: 1
});
}
return accumulator;
}
const output = data.reduce(getRegularIntervals, []);
console.log(output);
Output as expected:
[
{
"startDate": "01-07-2019",
"endDate": "10-07-2019",
"count": 10
},
{
"startDate": "15-07-2019",
"endDate": "16-07-2019",
"count": 2
},
{
"startDate": "20-07-2019",
"endDate": "23-07-2019",
"count": 4
}
]
I liked your approach of using reduce function.
Going with the same, I just added some more logic in there and here is the final code.
// initially lets assume first date is the start as well as end date
var dateIntervalObject = {
startDate: data[0].date,
endDate: data[0].date,
count: 1
};
var result = data.reduce((resultArray, obj, i) => {
if(i > 0) {
var startTime = moment(dateIntervalObject.endDate, "DD-MM-YYYY");
var endTime = moment(obj.date, "DD-MM-YYYY");
if (endTime.diff(startTime, 'days') === 1) {
dateIntervalObject.endDate = obj.date;
dateIntervalObject.count += 1;
// remove the latest object in array, to replace with new
resultArray.pop();
} else {
dateIntervalObject = {
startDate: obj.date,
endDate: obj.date,
count: 1
};
}
// push the date Interval object in the array
resultArray.push(dateIntervalObject);
}
return resultArray;
}, [dateIntervalObject]);
console.log('result: ',result);
Note:
When initialState of the accumulator is passed to reduce function it starts iterating from 0th index, which in our case have already been initialized in the dateIntervalObject and therefore the first iteration with index value 0 is skipped.
Also, if the interval is not changing, we don't need to add another object to our result array but instead update the end date of the last element of our result array. Therefore, first pop and then push to just update the end date and count value.
Hope this helps!

JavaScript: Compare dates in an array and sum the "price" for each month/year

I have a json file with multiple transactions with a date and a price attribute. Now I want to compare the dates and if they are in the same month and year I want to sum up the prices.
JSON:
transactions: [
{
date: "2017-11-17",
price: "28",
},
{
...
}
JavaScript:
request.onload = function() {
for(const transaction of request.response.transactions) {
let year = new Date(transaction.date).getFullYear();
let month = new Date(transaction.date).getMonth();
console.log(year + ' ' + month); // output: 2017-11 ...
}
};
I tried to loop over the json object but I struggle to find a solution to compare the dates.
Edit: Edited example with Object.assign instead of Object spread.
You'll need to use reduce to sum the prices. See comments for details.
const transactions = [{
date: "2017-11-17",
price: "28",
},
{
date: "2017-12-17",
price: "23",
},
{
date: "2017-11-17",
price: "12",
},
{
date: "2017-10-17",
price: "55",
},
{
date: "2017-11-17",
price: "09",
},
];
const sumTransactions = (transactions) => {
const summed = transactions.reduce((acc, current) => {
// Get the current date object
const date = new Date(current.date);
// Create your key/identifier
const key = `${date.getFullYear()}-${date.getMonth() + 1}`;
// Retreive the previous price from the accumulator
const previousPrice = acc[key]; // Might also return undefined
// Create your temp current price value, and be sure to deal with numbers.
let currentPrice = Number(current.price);
// If you had a previous value (and not undefined)
if (previousPrice) {
// Add it to our value
currentPrice += Number(previousPrice);
}
// Return the future accumulator value
return Object.assign(acc, {
[key]: currentPrice, // new values will overwrite same old values
})
}, {})
// Once we have all values, get the dates, and sort them (default: earlier first)
// Return an array of each value from the summed object to our sortedArray
const sortedArray = Object.keys(summed).sort().map((val) => {
return summed[val];
});
console.log("sortedArray", sortedArray);
};
sumTransactions(transactions);
I experimented a bit and came up with this solution:
var transactions = [
{
date: "2017-11-17",
price: "28",
},
{
date: "2017-12-17",
price: "22",
},
{
date: "2017-12-17",
price: "20",
}
]
var sumedUpDates = [];
var prices = [];
function isDateSumedUp(date) {
return sumedUpDates.indexOf(date.substring(0, 7)) !== -1;
}
function sumUpDate(date) {
var sum = 0;
transactions.forEach(t => {
if(t.date.substring(0, 7) === date.substring(0, 7)) {
sum += parseInt(t.price);
}
});
sumedUpDates.push(date.substring(0, 7));
prices.push(sum);
}
transactions.forEach(t => {
if(!isDateSumedUp(t.date)) {
sumUpDate(t.date);
}
});
var obj = {};
sumedUpDates.forEach((d, i) => obj[d] = prices[i]);
console.log(obj);
This solutions uses map to format your dates into year/month format for each object entry and then reduce to sum them by those separated dates.
const transactions = [
{date:"2017-11-17", price: "28",},
{date:"2017-12-17", price: "28",},
{date:"2017-11-17", price: "20",},
{date:"2017-12-17", price: "2",},
{date:"2017-11-17", price: "58",},
{date:"2017-11-17", price: "8",},
{date:"2017-10-17", price: "30",},
{date:"2018-11-17", price: "1",},
];
const mapper = single => {
let d = single.date.split('-');
let p = Number(single.price);
return { year: d[0], month: d[1], price: p };
}
const reducer = (group, current) => {
let i = group.findIndex(single => (single.year == current.year && single.month == current.month));
if (i == -1) {
return [ ...group, current ];
}
group[i].price += current.price;
return group;
};
const sumPrices = transactions.map(mapper).reduce(reducer, []);
console.log(sumPrices);
var array = [];
for (var i = 0; i < transactions.length; i++) {
var date = new Date(transactions[i].date);
var ym = date.getFullYear() + "-" + date.getMonth();
if (array[ym] == null) {
array[ym] = 0;
}
array[ym] += parseInt(transactions[i].price);
}
With this data
var transactions = [{
date: "2017-11-17",
price: "28",
},
{
date: "2017-12-17",
price: "5",
},
{
date: "2016-02-17",
price: "28",
},
{
date: "2015-11-17",
price: "25",
},
{
date: "2016-02-17",
price: "12",
},
{
date: "2017-11-17",
price: "50",
}
];
This will give you the sum of all of the year-months duplicates like this :
[
2017-10: 78,
2017-11: 5,
2016-1: 40,
2015-10: 25
]
Another solution is reduce:
var transactions = [
{date: "2017-11-17",price: "28"},
{date: "2017-12-17",price: "22"},
{date: "2017-12-17",price: "20"}
];
var result = transactions.reduce(function(acc, obj) {
var key = obj.date.substr(0,7);
acc[key] = (acc[key] || 0) + +obj.price;
return acc;
}, Object.create(null));
console.log(result);

Group multiple elements in array with JavaScript

I have an array
[
{ price: 10 },
{ price: 10 },
{ price: 10 },
{ price: 10 },
{ price: 20 },
{ price: 20 },
]
and I want it transformed into
[
{ numElements: 4, price: 10 },
{ numElements: 2, price: 20 },
]
I have tried using arr.reduce((prev, curr) => ..., []) to accomplish this, but I can't figure out how to do it.
A traditional method might use a for/loop to wrangle the data, but these days JavaScript has a number of functional methods that can help. This code uses reduce and map. To get your data in the format you want is a two stage process.
First, use reduce to create a hash table using the price as a key (because you know the each price is going to be unique:
const obj = arr.reduce((p, c) => {
// If price exists as a key its value by 1
// otherwise set it to 1.
p[c.price] = ++p[c.price] || 1;
return p;
}, {});
OUTPUT
{
"10": 4,
"20": 2
}
As it stands you've got a perfectly good object that you can access by the key/price and I would probably just stop there:
obj['10'] // 4
But if you want to get that data into the format in your question, map over the object keys to return an array of new objects.
const out = Object.keys(obj).map(key => {
return { price: +key, numElements: obj[key] };
});
DEMO
var hash = {}, result = [];
arr.forEach(function(el){
if(hash[el.price]){
hash[el.price].numElements++;
}else{
result.push(hash[el.price]={price:el.price,numElements:1});
}
});
Run
May use a hash table for price lookup. Or with reduce and find:
arr.reduce((res,{price})=>
(( res.find(el=>el.price===price) || res[res.push({price,numElements:0})-1] )
.numElements++,res)
);
Run
You can use try this:
let arr = [
{ price: 10 },
{ price: 10 },
{ price: 10 },
{ price: 10 },
{ price: 20 },
{ price: 20 },
]
let result = []
let counter = {}
arr.forEach( el => {
if (!counter[el.price]) counter[el.price] = 1
else counter[el.price]++
console.log(counter[el.price])
})
for (let id in counter) {
result.push({numElements: counter[id], price: id})
}
Assuming that the data comes sorted on price property, with a single .reduce() you may do as follows;
var data = [{ price: 10 }, { price: 10 }, { price: 10 }, { price: 10 }, { price: 20 }, { price: 20 }],
result = data.reduce((r,d,i) => i ? r[r.length-1].price === d.price ? (r[r.length-1].numElemenets++, r)
: (r.push(Object.assign({}, d, {numElemenets: 1})),r)
: [Object.assign({}, d, {numElemenets: 1})], {});
console.log(result);
You could look up the price in the result array and if not found insert a new object.
var data = [{ price: 10 }, { price: 10 }, { price: 10 }, { price: 10 }, { price: 20 }, { price: 20 }],
grouped = data.reduce((r, { price }) => {
var t = r.find(p => price === p.price);
t || r.push(t = { numElements: 0, price });
t.numElements++;
return r;
}, []);
console.log(grouped);

Javascript how to display the amount of users based on which month they are created

I want to display the amount of users based on which month they are created. I got the following data as example:
[
{ name: 'user1', created: 'may' },
{ name: 'user2', created: 'may' },
{ name: 'user3', created: 'may' },
{ name: 'user4', created: 'may' },
{ name: 'user5', created: 'june' },
{ name: 'user6', created: 'june' },
{ name: 'user7', created: 'august' },
{ name: 'user8', created: 'august' },
{ name: 'user9', created: 'august' }
]
what I want to achieve is to display them like this:
may: 4
june: 2
august: 3
How can I do that?
You can use reduce() and return object as result.
var data = [{"name":"user1","created":"may"},{"name":"user2","created":"may"},{"name":"user3","created":"may"},{"name":"user4","created":"may"},{"name":"user5","created":"june"},{"name":"user6","created":"june"},{"name":"user7","created":"august"},{"name":"user8","created":"august"},{"name":"user9","created":"august"}]
var result = data.reduce(function(r, e) {
return r[e.created] = (r[e.created] || 0) + 1, r
}, {})
console.log(result)
I think this will give you the idea:
const usersCreatedInMay = users.filter(u => u.created == 'may')
usersCreatedInMay will return null or an array. Just look at the length of it to learn how many users created in may.
usersCreatedInMay.length
You can loop through all months and calculate how many users created in each month.
You could try something that goes in this direction, code may not work since it is not tested.
function extract(month, data) {
return let result = data.filter((res)=>{
return res.created === month;
})
This is a pure javascript code you can use:-
var monthWithUsercount = {};
for (var i = 0; i < a.length; i++) {
var num = a[i];
monthWithUsercount[num.created] = monthWithUsercount[num.created] ? monthWithUsercount[num.created]+1 : 1;
}
//Here "a" is the array consisting months and users.
console.log(monthWithUsercount);
Here is the working fiddle - https://jsfiddle.net/sajalsuraj/7nychnd2/
Cheers!!

Categories