Accessing objects to find most frequent date

function loopingData2() {
  let most = 0
  let result
  let datesWithCounts = {}
  //access sale dates object
  let datesByCandyName = store2[`sale dates`]
  //get array values
  for (let candy in datesByCandyName){
    for (let i = 0; i < datesByCandyName[candy].length; i++){
      let currentDate = datesByCandyName[candy][i]
        if(!datesWithCounts[currentDate][i]){
          datesWithCounts[currentDate][i] = 1
        } else {
          datesWithCounts[currentDate][i]++
        }
    }
  }
    for (let date in datesWithCounts){
      if (datesWithCounts[date] > most){
        most = datesWithCounts[date]
        result = date
      }
    }
  return result
}

What sucks is just not understanding.

You don’t need the [i] on the end, because you have already accounted for i in the currentDate assignment line.

It passed thank you…I’m going to try and comment it as best as I can so I understand what is happening.

function loopingData2() {
  let most = 0
  let result
  let datesWithCounts = {}
  //access sale dates object
  let datesByCandyName = store2[`sale dates`]
  //get array values
  for (let candy in datesByCandyName){
    for (let i = 0; i < datesByCandyName[candy].length; i++){
      let currentDate = datesByCandyName[candy][i]
        if(!datesWithCounts[currentDate]){
          datesWithCounts[currentDate] = 1
        } else {
          datesWithCounts[currentDate]++
        }
    }
  }
    for (let date in datesWithCounts){
      if (datesWithCounts[date] > most){
        most = datesWithCounts[date]
        result = date
      }
    }
  return result
}

I have been wanting to show you my solution ever since I saw your post this earlier today. You will notice, I did not use the extra for loop at the end like you did. Also, for the inner for loop, I used a for of loop to avoid indexes.

function loopingData2() {
  const dateCounts = {};
  const candies = store2['sale dates'];
  let maxDate = '', maxCount = 0; 
  for (let candy in candies) {
    for (let date of candies[candy]) {
      const dateCount = dateCounts[date];
      dateCounts[date] = !dateCount ? 1 : dateCount + 1;
      if (dateCounts[date] > maxCount) {
        maxDate = date;
        maxCount = dateCounts[date];
      }
    }
  }
  return maxDate;
}

That’s what I’m confused about…for…of loops. I thought best practice is to used for…in loops for objects?

Since I did not need the index and only needed the value of each element, a for of loop was the most readable choice.

Almost done with the first week of the bootcamp…even when I struggle this bad, someone like me can seriously get to your type of efficiency? I get really down on myself a lot because I’m struggling so much.

With the amount of material you typically cover in a bootcamp, you are guaranteed to be stressed and feel overwhelmed. You just have to stick with it and make sure you ask lots of questions during a session of anything you do not understand. You won’t have time to understand later, because you will be practicing what you learned each night/before the next morning’s session.

1 Like

Thanks as always @RandellDawson. Truly.

Did you solve the other challenge you were working on in the other thread?

1 Like

Yeah, it was far too simple. I was overthinking.

I commented and refactored a little. Do these comments do justice to what is actually happening?

function loopingData2() {
  //date result to be returned
  let result
  //counter to keep track of most frequent date
  let most = 0

  //empty object to store incremented value
  let countedDates = {}
  //access `sale dates` object
  let candies = store2[`sale dates`]
  //get array values
  for (let key in candies){
    //loop through every value (dates) in `sale dates` object
    for (let i = 0; i < candies[key].length; i++){
      //store incremented values
      let currentDate = candies[key][i]
      //if the incremented value is there, increment by one
        if(countedDates[currentDate]){
          countedDates[currentDate]++
        } else {
          //else equal it to 1
          countedDates[currentDate] = 1
        }
    }
  }
    //block of code to check which has the most frequency
    //for every date in our object
    for (let date in countedDates){
      //if the frequency is greater than 0
      if (countedDates[date] > most){
        //set most to that frequency
        most = countedDates[date]
        //set the most frequent date to the result
        result = date
      }
    }
  return result
}

Are your comments just to help you remember what is going on or are you thinking this should be how you comment the code for others?

Comments should only document why you chose to do something and not what the code is doing. For example, you do not have to explain your if statements and you do not need to explain your loops, because they are explaining what the code does. If you have to write what code does, then change your variable names to something more meaningful which will better describe what is happening.

If you look at the code I wrote and posted last night, you will see I did not use variable names like key or i, because they do not explain what they are. One thing I think you should comment on which you did not is what candies[key] represents. A short comment that candies[key] represents the dates array for each candy would be good.

See below where I rewrote your code with minimal comments which explain why something was done. I good example of when to write a comment if inside the inner for loop where I explain why I incremented countedDate[date] or set it equal to 1. There is no reason to state you incremented the value of countedDate or set it equal to 1, because that is evident in the code. The two comments help you keep straight why you incremented vs. just setting the value equal to 1.

You will also notice that I changed many of your variable names, to eliminate the need to explain other parts of the code. See how I used candy in the for in loop and then created a variable named datesArray where I assigned candies[candy] to it. Now you do not have to explain what candies[candy] is. You now know it is an array of dates. Then in the inner for in loop, I can use idx (since we are looping through an array). I added one extra line just to make it more readable (the date = datesArray[idx] part). I also moved and renamed some of your declared variables closer to the code location which they are used. This keeps everything a little better organized.

function loopingData2() {
  let countedDates = {} // to store each date's count
 
  let candies = store2[`sale dates`]
  
  for (let candy in candies){
    let datesArray = candies[candy]
    for (let idx in datesArray){
      let date = datesArray[idx]
      if(countedDates[date]){ 
        countedDates[date]++ // date already exists
      } else {
        countedDates[date] = 1 // new date encountered
      }
    }
  }

  let mostFreqDate
  let mostFreqDateCount = 0

  for (let date in countedDates){
    if (countedDates[date] > mostFreqDateCount){ // check if a new max date count is found
      mostFreqDate = date
      mostFreqDateCount = countedDates[date]
    }
  }
  return mostFreqDate
}

@RandellDawson You are amazing, thank you, but just still being a newbie and a week into the bootcamp, I was asking if code like this is normal to get through a problem and then have it for understanding later. That’s all. As far as professional code? I wasn’t really expecting to hit that bar yet. :wink:

Yes, your comments seem to indicate you understand what the code is doing.

The earlier you can start thinking about writing your code in this way, the better off you will be in the long term. Plus, you will not have to make so many comments.

1 Like