Challenge 7 Megathread

Welcome to challenge 7! Use this thread for any and all questions relating to challenge 7.

Using Array.prototype.reduce:


const termTopics = (interviews) =>  interviews.reduce(([countA,countB,countC], interview)=> {
    switch(interview){
      case "smart city": return [countA+1,countB,countC];
      case "arts funding": return [countA,countB+1,countC];
      case "transportation": return [countA,countB,countC+1];
      default: return [countA,countB,countC];
    }
  },[0,0,0])
4 Likes

Here’s my solution:

Summary
const termTopics = (interviews) => {
  
  let smartCityCount = 0;
  let artsFundingCount = 0;
  let transportationCount = 0;
  const topicCount = [];
  
  //loop through the array
  for(let i=0; i<interviews.length; i++) {
    
    let topic = interviews[i]
    
    switch (topic) {
      case "smart city":
        smartCityCount++;
        break;
      case "arts funding":
        artsFundingCount++;
        break;
      case "transportation":
        transportationCount++;
        break;
      default:
        break;
    }
    
  }
  
  topicCount.push(smartCityCount);
  topicCount.push(artsFundingCount);
  topicCount.push(transportationCount);
  
  return topicCount;
  
}

I find that my solutions are sometimes a little long, so I am trying to figure out how to condense it!

1 Like

Can you explain your code? and explain what reduce does.

Thanks!

My solution:

const termTopics = (interviews) => {
  let TopicCount=[0,0,0];
  for (var i=0; i<interviews.length; i++){
    if (interviews[i]=="smart city"){
      TopicCount[0]++;
    }else if (interviews[i]=="arts funding"){
      TopicCount[1]++;
    }else if (interviews[i]=="transportation"){
      TopicCount[2]++;
    }
  }
  return (TopicCount);
};
4 Likes

But to quote those guys,

The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.

Example:

var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
  return accumulator + currentValue;
}, 0);
// sum is 6
1 Like

Similar, but with switch/case statement

const termTopics = (interviews) => {

var phraseCalculation = [0,0,0];

for (i=0; i < interviews.length; i++)
{
//checking value for array via switch statement
switch (interviews[i])
{
case “smart city” :
phraseCalculation[0]++;
break;
case “arts funding” :
phraseCalculation[1]++;
break;
case “transportation” :
phraseCalculation[2]++;
break;
}
}

return phraseCalculation;

}

1 Like

What is the purpose of “interview”? I assume it is somehow getting the values of the interviews array, but I’m also confused to how the reduce function works.

Makes 3 of us confused by it.

1 Like

Very cool answer, it didn’t occur to me to use an array as my accumulator and I did the solution in two steps instead of 1.

const termTopics = (interviews) => {
  const count = interviews.reduce((acc, cv) => {
    return {...acc, [cv]: acc[cv] ? acc[cv]+1 : 1}
  }, {})
  return [count['smart city'], count['arts funding'], count['transportation']];
}

You kinda made it more complex…lol

So! I really do recommend going through the mdn link and examples, and it is 4 AM here, but the gist of it is:

A reducer reduces things. now, how would it do it?
it take a function and (possibly) an initialAccumulator value.
And so it goes through the array.

so, suppose we want to sum up [1,2,3,4].
All we need to do is to keep the sum in an accumulator. start with 0, then its 1, then 3, then 6 and finally 10.

function sumReducer(accumulator, element) { 
  const newAccumulatorValue = accumulator + element;
  return newAccumulatorValue;
}
[1,2,3,4].reduce(sumReducer, 0);

and so all it is doing is this:

(0, 1) -> 1
(1, 2) -> 3
(3, 3) -> 6
(6, 4) -> 10

notice how the first argument is 'accumulating things? and the second argument is just the next element of the array.

In the specific case of what I posted, the trick is to start with [0,0,0]. That is the count for the three things we want, right?
and our reducer function is just taking this accumulator ([0,0,0]) and then checking the element (the interview) and being like… oh! I found a ‘smart city’, well, clearly I have to update the accumulator!
And then using the same function on the next element with our new accumulator.

And so on and so forth.

Take the example array:

    const interviews = [
      'smart city', 
      'rebuild the lighthouse', 
      'arts funding', 
      'transportation',
      'arts funding', 
      'rebuild the lighthouse', 
      'sports funding', 
      'tax cuts', 
      'smart city',
      'arts funding', 
      'smart city'
    ]

my reducer is going on like so:

([0,0,0], 'smart city') -> [1,0,0]
([1,0,0], 'rebuild the lighthouse') -> [1,0,0]
([1,0,0], 'arts funding') -> [1,1,0]
([1,1,0], 'transportation') -> [1,1,0]
//etc...

Please check out the MDN link. I think it’s fairly transparent what’s going on there.

Good night!

1 Like

using an if statement, i was able to achieve mine.

Though its a bit longer, but thats the only solution i can verify true.

1 Like

I used a filter inside a for loop and seems to have worked and let me submit. Not sure why it doesn’t like me using it though (I get a debug notification that says to not use functions inside a loop).

1 Like

hi jack

your code is clear and logical. Good job. One suggestion is to destructure your variables.
you could use this:

let [smartCityCount, artFundingCount, transportationCount] = [0,0,0];

after your loop and switch statement just return the array. no need to push to it.

return [smartCityCount, artFundingCount, transportationCount];

A quick review of regular functions vs arrow functions and a solution to the day 7 challenge using if statements. Enjoy: https://youtu.be/TwImdLmGvpI

Here’s my solution for those interested.
The switch method could be replaced with if else statements if you prefer. I think this is easier to read though (and hence, better).

const termTopics = (interviews) => {
  let topicCount = [0,0,0]
  for(const topic of interviews){
    switch (topic){
      case "smart city":
        ++topicCount[0];
        break;
      
      case "arts funding":
        ++topicCount[1];
        break;
      
      case  "transportation":
        ++topicCount[2];
        break;
      
    } //switch
  }//for
  
  return topicCount
}

Hope this helps!

1 Like

Adding to the list of solutions here.

const termTopics = (interviews) => {
  return [
    interviews.filter(function(interview){return interview=='smart city'}).length,
    interviews.filter(function(interview){return interview=='arts funding'}).length,
    interviews.filter(function(interview){return interview=='transportation'}).length
    ]
}
4 Likes