the output shoud be true or false, if the acc is equal to target then change the acc to be true (so I reassign it ) I don’t know, maybe I didnt get what you wanted to say
I would suggest l logging out data to see what is happening:
const countLetters = function (string) {
let count = {};
const letters = string.split("");
console.log(letters);
let obj = letters.reduce((acc, curr) => {
if (acc.hasOwnProperty(acc[curr])) {
console.log('incrementing', acc, curr);
return (acc[curr] += 1);
} else {
console.log('initializing', acc, curr);
return (acc[curr] = 1);
}
console.log('Can this code *ever* be hit?');
return acc;
}, count);
return obj;
};
console.clear();
console.log(countLetters("abbcccddddeeeee"));
Ultimately I was able to get this to work by fixing three lines.
if (acc.hasOwnProperty(acc[curr])) {
Is that what you want to check? Do you want to check if it has the property of acc[curr]? Ask yourself what that variable contains.
return (acc[curr] += 1);
and
return (acc[curr] = 1);
For example, put a console.log before that second one and see what acc[curr] = 1 evaluates to. Remember that what we return here is what the new acc will become. We don’t need to change the current acc, we just need to return what we want the acc to be in the next iteration.
I did this the console.log shows the obj with the letter counted but don’t know why I cant take them out, also if i return if and else blocks I get a 1 in console.log, but not anything in the obj, why is this??
const countLetters = function(string){
//your code here
let count={};
const letters = string.split('');
console.log(letters);
let obj = letters.reduce((acc, curr)=>{
/* console.log(curr) */
console.log(acc)
if (Object.keys(acc).includes(curr)){
acc[curr]= acc[curr]+1;
}else{
acc[curr]= 1;
}
return acc;
}, count)
};
countLetters('abbcccddddeeeee')
Still, you’re trying to assign what you want. Don’t. Return what you want. And what is acc? It’s an object … so you have to return an object. How do you make a new object with that new property? There are a couple ways, but I think it would be a nice chance to use a spread operator.
Because, return (acc[curr] = 1); is returning 1 because acc[curr] = 1 evaluates to 1 and that’s what you’re telling reduce that you want the next acc to be.
Yes, the prototype methods are a little confusing, and none of them are worse than reduce. I’ve even met senior devs that didn’t know how to use it. But it is learnable and it is very powerful.
so here am I turning the obj into an arr that why it doesn’t work in if/else? I wanted to use this acc[curr] = 1 to set the first value to one in case I see that key for the first time.
so here am I turning the obj into an arr that why it doesn’t work in if/else?
That isn’t turning the object into anything - it is returning the keys and leaving the object unaffected. That isn’t a problem. But I think Randy is right - _ hasOwnProperty_ is better - you were just checking for the wrong property.
I wanted to use this acc[curr] = 1 to set the first value to one in case I see that key for the first time.
That’s fine the way you have that now - it just didn’t work when you were trying to return that expression directly.
I wanted to use this acc[curr] = 1 to set the first value to one in case I see that key for the first time.
To be clear, there is a difference between:
return acc[curr] = 1;
and
acc[curr] = 1;
return acc;
In the first one, you’re altering acc but returning what the expression acc[curr] = 1 evaluates to (the number 1). In the second one you’re altering acc again and then returning acc.