# Reduce exercise, how should I do?

Hello! Can you explain to me how should I solve these what am I doing wrong??

``````const isPresent = function(string, target) {
const letters = string.split('');
console.log(letters);
letters.reduce((acc,curr)=> {
console.log(acc)
if(acc===target){
return acc=true;
} else {
return acc=curr;
}

return acc;
})
}

isPresent('abcd', 'b') // => true

const countLetters = function(string){
let count={};
const letters = string.split('');
console.log(letters);
let obj = letters.reduce((acc, curr)=>{
console.log(acc)
if (acc.hasOwnProperty(acc[curr])){
return acc[curr] += 1;
} else {
return acc[curr]=1;
}
return acc;
}, count)
};

countLetters('abbcccddddeeeee') // => {a:1, b:2, c:3, d:4, e:5}
``````

Solution for the first problem (in case someone will wonder):

``````const isPresent = function(string, target) {
const letters = string.split('');
console.log(letters);
let boo= letters.reduce((acc,curr)=> {

if(curr===target){
return acc=true;
} return acc;
}, false);
return boo;
}
``````

for the second, down in the comment, there is the solution. Thank you everyone who helped me!

First thing that stands out for me is that youâ€™re using assignment operator `=` in return statement. Try using strict equality `===` instead

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){
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.

You are better off with the `hasOwnProperty` method here. Converting the object back into an array and using `indexOf` on it is overly complicated and less efficient than just checking if the letter exists in the object using `hasOwnProperty`.

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.

Actually, your latest version is basically working, you just forgot to return the result from _ countLetters_.

1 Like

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.

Omg!! Thanks! I thought the reduce was wrong I couldnâ€™t see. It is 2/3 days that I am trying to learn how to use reduce, so I am still confuse.

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.

1 Like

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.

I got now, thank you for helping me and your time!

1 Like

And one last point, actually I think the cleanest version of this:

``````    if (Object.keys(acc).includes(curr)){
``````

would be:

``````   if (acc[curr]) {
``````

Once itâ€™s set, it will always be truthy.

1 Like

thanks! Yes, that is a good advise