0

I am working on a firebase project with vuejs, trying to draw a chart that shows the number of subscribers per month. The main issue is to just calculate the number of created profiles for each month. The rest of the steps will be okay with me.

I thought to do something like this:

// calculation of number of users each month
let months = ['jan', 'feb', 'mar', 'apr', 'may', 'Jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];

this.users.filter(user => {
  let print = user.metadata.creationTime;

  for (var month in months) {
    if (print.indexOf(month) > -1) {
      console.log(user.email)
    }
  }
})

I imagined it like this,.. but the console prints duplicated records for each month,..

I am thinking that there might be another way of doing it,.. or do I just stick with tweaking and trying with this one?

3
  • 3
    It's not currently clear what you're trying to do. What is your expected output? What does your input look like? Commented Sep 30, 2019 at 19:03
  • I think you mean month of months rather than in. Currently you're iterating the numeric indices. I would also note that Jun is not in the same case as the other months. Also unclear why you're using filter, seems unlikely to be the appropriate iterator. Commented Sep 30, 2019 at 19:15
  • I would avoid indexOf() and replace it with includes(). Also, I agree with @skirtle. for...of is meant more for array and for...in is meant more for objects' keys. filter is meant to return some object(s) based on certain criteria, and it doesn't look like you're attempting that. Can you provide more context as well? Commented Sep 30, 2019 at 19:20

1 Answer 1

1

I think you're aiming for something like this:

// Mock data
const users = [
  { metadata: { creationTime: '3 apr' } },
  { metadata: { creationTime: '7 apr' } },
  { metadata: { creationTime: '26 jan' } },
  { metadata: { creationTime: '4 feb' } },
  { metadata: { creationTime: '9 dec' } },
  { metadata: { creationTime: '25 dec' } },
  { metadata: { creationTime: '9 apr' } }
]

// Months in lower-case... creationTime is assumed to also use lower-case
const months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']

// Use `map` to create an array the same length as `months`
const counts = months.map(month => {
  let count = 0
  
  // Loop over the `users` array, note the use of `of`, not `in`
  for (const user of users) {
    // Using `includes` is somewhat crude but may work depending on how
    // creationTime is formatted. It's no worse than indexOf
    if (user.metadata.creationTime.includes(month)) {
      ++count
    }
  }
  
  return count
})

console.log('Counts: ' + counts.join(' '))

The output in this case is an array containing the counts for each month but you could easily adapt the return value inside the map function to return an object with the month name and count if that'd be easier to work with.

As I noted in the comments the main flaw in your original code is the use of for (var month in months) {. That will iterate over the numeric indices rather than the month names, so you're just checking for 0, 1, 2, etc. rather than jan, feb, mar, etc.. To iterate over the contents of the array you would need to use a for/of loop instead.

Sign up to request clarification or add additional context in comments.

2 Comments

oh! didn't take that in consideration! I will try it .. Thanks for that!
Now I learnt something! I must use for / of loop for arrays :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.