[React, JS] Count occurrences of strings in object?

Hello all,

I’m attempting to count the number of occurrences, but I just can’t figure it out. Been looking at map, concat, etc.

Here’s my most recent attempt:

render(){
  const chartMoments = [
    {  
      location: "Office",
      mental: "Some",
      environmental: "None"
    } 
    // ...
  ]
  const counter = () => {
    chartMoments.map(moment => {
      let noneCount = 0;
      let aLittleCount = 0;
      let someCount = 0;
      let aLotCount = 0;
    }

    if(moment.environmental === 'None') {
      noneCount++;
      return noneCount
    }
    console.log(noneCount);
  }
}

The problem is, I just can’t seem to increment them. It increments by 1 at that time, but does not store it and continue incrementing. I tried forEach as well. But maybe I’m just getting lost in the order in which to do things?

the thing is, thevariables are local, so each time the function is called, they are initialised again at 0, so they exist only inside the callback, and also reach max 1
forEach can be a good guess, but you need variables outside the method to increment. reduce will work too, but it needs a bit more effort to plan it.

I also suggest you review what map and concat do - maps will return a new array with the values returned by the ballcack for each element, concat will concatenate two things. they are not that useful in this situation.

Oof. I guess I’m really not sure what to do then. :confused:

There are a few issues with your code here I’ll break it down for you:

  1. Like what ieahleen said, you are initiating your variables in the map function itself here. You also forgot to close the backets up for your map statement as well as provide the semi-colon.

What you should be doing is declaring your variable outside of the map function, another problem with doing that that is you can’t use the variable that you have declared inside the map function outside of the function itself.

  1. Your logic is outside of the map function. It should be inside the map function as you are using the named value “moment” in your if statement.

  2. Your return statement is above your console.log statement. You wouldn’t be console logging anything at all if the environmental key in your object is “None”. Thats because you returned noneCount and after you call return on any function, the function will exit itself.

Thanks @Keneri.

Looks like after I pasted I reformatted wrong. I was indeed initiating those variables inside the map function, but the if statement was correct.

Here:

    const counter = () => {
      let noneCount = 0;
      let aLittleCount = 0;
      let someCount = 0;
      let aLotCount = 0;
      chartMoments.map(moment => {
        if (moment.environmental === 'None') {
          return noneCount++;
        }
      });
      console.log(noneCount);
    };

I wonder why I did that… I know better…

Anyways, the console.log is now showing the correct amount of occurrences for the dummy data.

Is there a more succinct way of doing this?:

      chartMoments.map(moment => {
        if (moment.environmental === 'None') {
          return noneCount++;
        }
        if (moment.environmental === 'A Little') {
          return aLittleCount++;
        }
        if (moment.environmental === 'Some') {
          return someCount++;
        }
        if (moment.environmental === 'A Lot') {
          return aLotCount++;
        }
      });

edit: Also, I do see that I’m not using map appropriately here. I do want to create an array with these values, however.

Your code looks correct so it should show the correct amount of occurrences, maybe double check your dummy data and expect output again?

There’s only one other way I see to make the if statements more succinct is to remove the curly brackets and just return the counter in 1 line:

if (moment.environmental === "None") return noneCount++;
if (moment.environmental === "A Little") return aLittleCount++;
if (moment.environmental === "Some") return someCount++;
if (moment.environmental === "A Lot") return aLotCount++;

Edit: There is another way which is to use conditional operators, but I think it isn’t as clear as if statements in this case.

moment.environmental === "None"
        ? noneCount++
        : moment.environmental === "A Little"
        ? aLittleCount++
        : moment.environmental === "Some"
        ? someCount++
        : moment.environmental === "A Lot"
        ? aLotCount++
        : "Error! Data not found.";

if you don’t use the feature that map returns an array with the elements of the original array but changed by the callback, don’t use map

you have available forEach for that…