Each_with_object works with array as memo_obj, but doesn't with string or integer

#1

ruby 2.6.3p62 (2019-04-16 revision 67580) [x64-mingw32]

The code below should display the longest word in the input string. The second line (1) works as expected while the third one (2) doesn’t. The only difference is the class of the memo_obj: array (1) and string (2). Who can explain?

strng = "hffu dkifuehdid cfstdg ,fptktrkfnjdud dhhd fpoojkuwi fkdosksm "
puts strng.split(/\s/).each_with_object([""]){|x,i|i[0]=x.size>i[0].size ? x : i[0]}
puts strng.split(/\s/).each_with_object(""){|x,s|s=x.size>s.size ? x : s}

#2

Well, you are mutating the array at the 2nd line (which doesn’t change the object_id), but on the 3rd line, you are reassigning the string. So the string no longer refers to the original object in the reduce.

So what you can do is:

strng = "hffu dkifuehdid cfstdg ,fptktrkfnjdud dhhd fpoojkuwi fkdosksm "

puts strng.split.each_with_object(['']) { |x, i| i[0] = x.size > i[0].size ? x : i[0] }
puts strng.split.each_with_object(['']) { |x, i| i.replace([x]) if x.size > i[0].size }
puts strng.split.each_with_object('') { |x, s| s.replace x.size > s.size ? x : s }

# Efficient
puts strng.split.each_with_object('') { |x, s| s.replace(x) if x.size > s.size }

# Select multiple elements
strng.concat(('a'..'n').to_a.join)
strng.split.group_by(&:length).max[1].display

Produces:

,fptktrkfnjdud
,fptktrkfnjdud
,fptktrkfnjdud
,fptktrkfnjdud
[",fptktrkfnjdud", "abcdefghijklmn"]
#3

Thank you for this perfect coaching!

1 Like
#5

I am a beginner in ruby-forum, and just curious - why do you want to remove the post? I think this question can help someone in the future. Can’t it?

#6

Yes, It can.
I found few tutorials, and they don’t answer this question.
https://www.tutorialspoint.com/ruby/
ruby-doc.com/docs/ProgrammingRuby/
rubylearning.com
https://en.wikibooks.org/wiki/Ruby_Programming
But I’ve found an answer googling “ruby &:”.