Need help on Enumerable#slice_before

I wrote the code as below :-

input = ['11','12','12','12','11','11','12','44','44']

prev = 0
output = input.slice_before do |e|
input[prev = prev + 1] == e
end.to_a

p output # => [["11"], ["12"], ["12", "12"], ["11", "11", "12"], ["44", "44"]]

I am looking for output as [["11"], ["12", "12", "12"], ["11", "11"], ["12"], ["44", "44"]] using the same method .

What wrong I did here ?

Regards,
Arup Rakshit

Your are looking ahead instead of back because you compare element at
pos 0 with element at 1 and so forth.

irb(main):011:0> prev = 0
  printf "last %p this %p %p\n", input[prev+1], e, input[prev+1] == e
=> 0
  input[prev = prev + 1] == e
end.to_airb(main):012:0> output = input.slice_before do |e|
irb(main):013:1* printf "last %p this %p %p\n", input[prev+1], e,
input[prev+1] == e
irb(main):014:1> input[prev = prev + 1] == e
irb(main):015:1> end.to_a
last "12" this "11" false
last "12" this "12" true
last "12" this "12" true
last "11" this "12" false
last "11" this "11" true
last "12" this "11" false
last "44" this "12" false
last "44" this "44" true
last nil this "44" false
=> [["11"], ["12"], ["12", "12"], ["11", "11", "12"], ["44", "44"]]

You are making it more complicated than necessary - and depend on
Array as Enumerable at the same time. Since you do have variable prev
already you should just store the previous element there:

irb(main):002:0> input = ['11','12','12','12','11','11','12','44','44']
=> ["11", "12", "12", "12", "11", "11", "12", "44", "44"]
irb(main):003:0> prev = nil
=> nil
irb(main):004:0> output = input.slice_before {|e| (e != prev).tap {prev = e}}
=> #<Enumerator: #<Enumerator::Generator:0x0000060036a848>:each>
irb(main):005:0> output.to_a
=> [["11"], ["12", "12", "12"], ["11", "11"], ["12"], ["44", "44"]]

Btw. here's another way

irb(main):017:0> input.each_with_object() {|e,a| l=a.last; l && l[0]
== e ? l << e : a << [e]}
=> [["11"], ["12", "12", "12"], ["11", "11"], ["12"], ["44", "44"]]

Cheers

robert

···

On Fri, May 9, 2014 at 12:52 PM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

I wrote the code as below :-

input = ['11','12','12','12','11','11','12','44','44']

prev = 0
output = input.slice_before do |e|
  input[prev = prev + 1] == e
end.to_a

What wrong I did here ?

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

On Fri, May 9, 2014 at 12:52 PM, Arup Rakshit

You are making it more complicated than necessary - and depend on
Array as Enumerable at the same time. Since you do have variable prev
already you should just store the previous element there:

irb(main):002:0> input = ['11','12','12','12','11','11','12','44','44']
=> ["11", "12", "12", "12", "11", "11", "12", "44", "44"]
irb(main):003:0> prev = nil
=> nil
irb(main):004:0> output = input.slice_before {|e| (e != prev).tap {prev = e}}
=> #<Enumerator:
#<Enumerator::Generator:0x0000060036a848>:each>
irb(main):005:0> output.to_a
=> [["11"], ["12", "12", "12"], ["11", "11"], ["12"], ["44", "44"]]

It is awesome!!! Nice art you have created. I was damn sure that it can be done using *slice_before* method.

Regards,

Arup Rakshit

···

On Friday, 9 May 2014 7:29 PM, Robert Klemme <shortcutter@googlemail.com> wrote

Hi Arup,

(Yes, I know you're training the use of #slice_before... but...)

Just to note that the same is possible like...

input.chunk {|v| v}.map {|_, v| v}

Abinoam Jr.

···

On Fri, May 9, 2014 at 11:56 AM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

On Friday, 9 May 2014 7:29 PM, Robert Klemme <shortcutter@googlemail.com> > wrote
On Fri, May 9, 2014 at 12:52 PM, Arup Rakshit

You are making it more complicated than necessary - and depend on
Array as Enumerable at the same time. Since you do have variable prev
already you should just store the previous element there:

irb(main):002:0> input = ['11','12','12','12','11','11','12','44','44']
=> ["11", "12", "12", "12", "11", "11", "12", "44", "44"]
irb(main):003:0> prev = nil
=> nil
irb(main):004:0> output = input.slice_before {|e| (e != prev).tap {prev =
e}}
=> #<Enumerator: #<Enumerator::Generator:0x0000060036a848>:each>
irb(main):005:0> output.to_a
=> [["11"], ["12", "12", "12"], ["11", "11"], ["12"], ["44", "44"]]

It is awesome!!! Nice art you have created. I was damn sure that it can be
done using *slice_before* method.

Regards,

Arup Rakshit

Hello Abinoam,

Thanks for your reply and to get my point. But you see, with the method I choose, need only one iteration and done. :slight_smile: @Robert made it very very sweet too. :slight_smile:

Regards,
Arup Rakshit

Hi Arup,

(Yes, I know you're training the use of #slice_before... but...)

Just to note that the same is possible like...

input.chunk {|v| v}.map {|_, v| v}

Abinoam Jr.

···

On Friday, 9 May 2014 9:32 PM, Abinoam Jr. <abinoam@gmail.com> wrote:

On Fri, May 9, 2014 at 11:56 AM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

On Friday, 9 May 2014 7:29 PM, Robert Klemme <shortcutter@googlemail.com> > wrote
On Fri, May 9, 2014 at 12:52 PM, Arup Rakshit

You are making it more complicated than necessary - and depend on
Array as Enumerable at the same time. Since you do have variable prev
already you should just store the previous element there:

irb(main):002:0> input = ['11','12','12','12','11','11','12','44','44']
=> ["11", "12", "12", "12", "11", "11", "12", "44", "44"]
irb(main):003:0> prev = nil
=> nil
irb(main):004:0> output = input.slice_before {|e| (e != prev).tap {prev =
e}}
=> #<Enumerator: #<Enumerator::Generator:0x0000060036a848>:each>
irb(main):005:0> output.to_a
=> [["11"], ["12", "12", "12"], ["11", "11"], ["12"], ["44", "44"]]

It is awesome!!! Nice art you have created. I was damn sure that it can be
done using *slice_before* method.

Regards,

Arup Rakshit