nus-cs2030 / 2021-s2

2 stars 2 forks source link

AY20-21 sem 1 qn 6e #395

Closed Zekeseoj closed 3 years ago

Zekeseoj commented 3 years ago

Summary

Hello, how can i write the code for reduce in part e?

Description

Post the question that you would like your peers or seniors to answer.

Suggested Answer (if any):

Post your answer or the suggested answer, if any.

Screenshots (if any):

1231

rljw commented 3 years ago

The idea is pretty similar to part (d), except now u skip over the .map() function by using the reduce​(U identity, BiFunction<U,​? super T,​U> accumulator, BinaryOperator<U> combiner) function in streams. Think about how you want to accumulate values to increment your seed by the length of each word, which will help in formulating the lambda expression for accumulator. Hope this hint helps!

eltonngkk commented 3 years ago

Hi, you can either add them as a string using the reduce(identity, accumulator) then do a .length(), or you can use the reduce with the combiner, if you want to use identity as a integer, which would involve the use of more than 1 type, which the reduce with 2 parameters does not allow for. You can refer to this, it has pretty good explanations. https://stackoverflow.com/questions/24308146/why-is-a-combiner-needed-for-reduce-method-that-converts-type-in-java-8

yx0555 commented 3 years ago

hello, from the comments above there are many ways to do this but i first did .length(), then use the combiner to add them up

int count(List words) { return words.stream(). reduce(0, (x,y)->x+y.length(), (x,y)->x+y); }

Zekeseoj commented 3 years ago

What if i were to create this instead? words = [ "test1", "test2", "test4"]

int count(List words) { return words.stream() .reduce("", (x,y) -> x.length() + y, (x,y) -> x + y); }

So i basically tried to reverse it to see how the combiner would combine strings in this case, but the output seems to give "6test4", showing that it does not seem to combine each string made? Am I misunderstanding how combiner works for this operation?

ShyamalSankar commented 3 years ago

This stream is sequential so the combiner is not used

brendancjz commented 3 years ago

Also, it seems like that method you use to reverse 'it' is wrong. If you want to reverse the elements in the lift by reducing it into one long String, you can write it as such: Arrays.asList(words).stream().reduce("", (x,y) -> y + x);.

From the link that @eltonngkk shared, we can better understand the use of combiner in a sequential stream. Go check it out if you have not.

Zekeseoj commented 3 years ago

For my example, is it not possible to combine to form 0test16test26test4? Sry if it's unclear but I note that the individual 0test etc came from the accumulator. If we look at the correct implementation from the qn, why does the combiner(int type)work by adding each word.length() but my example doesn't work for the combiner(string type)? Of course I am probably wrong and might just be confused on how this thing works so I hope someone can enlighten me.

clementyee303 commented 3 years ago

For my example, is it not possible to combine to form 0test16test26test4? Sry if it's unclear but I note that the individual 0test etc came from the accumulator. If we look at the correct implementation from the qn, why does the combiner(int type)work by adding each word.length() but my example doesn't work for the combiner(string type)? Of course I am probably wrong and might just be confused on how this thing works so I hope someone can enlighten me.

Regardless of sequential or parallel stream, you need to include a combiner in order to call the overloaded reduce method that accepts a bifunction accumulator rather than a binaryoperator accumulator. As mentioned by others, the combiner is simply there to call the reduce method and is not actually used as this is not a parallel stream.

Now the reason why there isnt a reduce method for sequential streams that just has a bifunction accumulator is because streams were designed to have the same implementation for sequential and parallel streams (as long as you follow the rules)

Note the combiner has to be compatible with the accumulator too

Edit: to answer why your example is giving "6test4" here is what is happening: "".length() + "test1" = "0test1" "0test1".length() + "test2" = "6test2" "6test2".length() + "test4" = "6test4"

Zekeseoj commented 3 years ago

thanks, clement! I got it now.