Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialAkash Sharma
Full Stack JavaScript Techdegree Student 14,147 Pointsreturn count + 1 vs. return count++
Why am I getting 0 for this code:
const names = ['Gary', 'Pasan', 'Gabe', 'Treasure', 'Gengis', 'Gladys', 'Tony'];
const gNames = names.reduce((count, name) => {
if (name[0] === 'G'){
return count++;
}
return count;
}, 0);
console.log(gNames);
And 4 for this code:
const names = ['Gary', 'Pasan', 'Gabe', 'Treasure', 'Gengis', 'Gladys', 'Tony'];
const gNames = names.reduce((count, name) => {
if (name[0] === 'G'){
return count+1;
}
return count;
}, 0);
console.log(gNames);
3 Answers
Steve Hunter
57,712 PointsAgree. Neil, my answer didn't really cover the issue - that's me skim-reading as usual!!
I think this might be to do with the use of two return
statements. If you code this with one return, as I normally would (I don't use node or js, though!), and just return the value of count
at the end, then this behaves how I would expect:
const gNameCount = names.reduce((count, name) => {
if (name[0] === 'G'){
count + 1;
}
return count;
}, 0);
This returns zero as the value held in count
is never altered, so we get the specified initial value of zero, whereas:
const gNameCount = names.reduce((count, name) => {
if (name[0] === 'G'){
count++;
}
return count;
}, 0);
... returns 4 as we are modifying the value in count
with the increment operator, then returning that value at the end.
In this next example, maybe count
is an accumulator picking up the returned value on each iteration, perhaps? Thus it would add one (initial value + 1) on each iteration of a letter starting with 'G', storing that in count
as an accumulator? A letter not starting with 'G' would 'accumulate' a zero (the initial value) and thus not affect adversely what we would expect to see.
const gNameCount = names.reduce((count, name) => {
if (name[0] === 'G'){
return count + 1;
}
return count;
}, 0);
But, I don't understand why using return count++
produces, specifically, zero. I would expect it to mess with the loop, perhaps, and maybe generate unexpected results - but not zero. It is as if the reduce
function is just not working?!
This doesn't work in my mind:
const gNameCount = names.reduce((count, name) => {
if (name[0] === 'G'){
return count++;
}
return count;
}, 0);
I can understand this creating odd results, as if we're accumulating G's but adding one to count
, the first 'G' would correctly accumulate a 1, but the second would accumulate a 2, the third a 3 etc. Thus we'd get a large number output at the end. But we don't see this - we get, consistently, a zero.
I did some logging - this works very nearly as we would expect:
const gNameCount = names.reduce((count, name) => {
if (name[0] === 'G'){
console.log(count++)
return count;
}
return count;
}, 0);
console.log(gNameCount);
I'm logging the value of count
at each iteration. I get this output:
treehouse:~/workspace$ node iteration.js
0
1
2
3
4
5
But that's not right, is it? (although it has fixed the code - which now outputs the right number - I've added an extra 'G' name in the array, hence a 5). Why aren't there two 5s at the end, one mid-code and then the final output from the console.log
underneath the method? And how come this works all of a sudden? That got me thinking about timing of the increment. I think that return count++;
returns count
then increments it. But that change is lost so count
remains as zero, the change isn't included in the return
ed value, as it is returned first, so that change is dropped. I tested this theory with this:
const gNameCount = names.reduce((count, name) => {
if (name[0] === 'G'){
console.log(count)
return ++count;
}
return count;
}, 0);
This increments count
first by using the increment operator before the variable, and so the change is persisted into the next iteration. This works and solves your problems and answers your question! The reason your were getting zero was because the increment operator hadn't operated by the time the value was returned so the increment never happened. You need to increment with a preceding ++
operator to persist that change - i.e. to return an updated value for count
.
The act of return
ing the value of count
must update its value within the reduce
method. The use of either + 1
or ++
is irrelevant - it just wants to know what value to store. The count++
method doesn't work as the increment is too late so using either a preceding ++
or just sending back count + 1
is sufficient to update the value held within the iteration.
So, apologies for a few things - 1. the initial nonsense answer I gave back in November, 2. the thought-process post presented here; I literally typed this as I tested!
I hope this now answers the question and I am redeemed.
Your thoughts are welcomed!
Steve.
Steve Hunter
57,712 PointsHi there,
count + 1
doesn't affect the value of count
- you would need to reassign back into count
, like: count = count + 1
. Otherwise, you are just returning the value one greater than stored in count
. The increment operator does what it says; increments! So it affects the value stored within count
.
Steve,.
Neil McPartlin
14,662 PointsHi Steve Hunter & Akash Sharma,
I seem to be having a brain freeze here because although I understand your answer Steve, it doesn't actually explain what Akash and I are witnessing. Just to recap...
return count++; // This fails.
//My expectation like for Akash is that it would increment 'count' by one.
return count = count + 1; // This works and I'd guess we all agree why.
return count + 1; // This works but why?
//As Steve says, it should not succeed in incrementing 'count' by 1,
//but it does. In fact, this is the solution shown by the teacher in the video.
It feels like different rules apply when incrementing 'count' within a 'reduce' function.
Justin Hicks
14,290 PointsI realize this is not the most recent conversation, but I definitely hope you guys know how much I appreciate the in-depth answer. It has opened my eyes to just how specific code can be. While I did not do it exactly as the teacher or you guys did, the same issue persisted for my code. This resulted in 0;
const beginG = names.reduce((count, name) => {
if(name.startsWith('G') === true) {
count + 1;
}
return count;
}, 0);
console.log(beginG);
While this had the correct result of 4.
const beginG = names.reduce((count, name) => {
if(name.startsWith('G') === true) {
return count + 1;
}
return count;
}, 0);
console.log(beginG);
Again thank you guys for the indepth conversation. It has helped me more then you know!
Steve Hunter
57,712 PointsGlad to have helped a little, Justin!
Neil McPartlin
14,662 PointsNeil McPartlin
14,662 PointsHi Steve. Not only have you redeemed yourself, you have excelled yourself too :)
I follow and agree with pretty much everything you have written. I was unaware of ++count let alone the big difference it makes as to which side of the count, placing your ++ makes. I think I understand your logging issue too.
I just took your code and added some additional labels (plus a 5th G name).
So with your code, even with the first G match, count++ still reports 0 presumably until 'return count' takes place. This is why your initial log only shows a single 5. If you were to comment out the count++ log, and uncomment the ++count log, this would look more like you had expected with ++count reporting the same as count..
Thanks so much for your time on this.
Steve Hunter
57,712 PointsSteve Hunter
57,712 PointsHi Neil,
Thanks for the feedback; it annoyed me that I couldn't figure out what was going on, so I invested a little time on this, and dug out a distant memory regarding the placement of the
++
operator!Yes, the log occurs before the increment on each iteration now, so the log will be 'behind' the variable value as it exits each iteration.
Glad to have helped sort this despite not being a js developer! It just goes to show that the basic principles are common across most languages!
Steve.
Caleb Waldner
19,567 PointsCaleb Waldner
19,567 PointsGreat answer, very helpful. I still have a question about the return keyword. I understand that
return count++
returns count before it is updated. But why doesreturn count + 1
work? Shouldn't this also return count before it is updated?