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”]] usingthe same method.

What wrong I did here ?

Regards,
Arup R.

are you sure you want slice_before?

[‘11’,‘12’,‘12’,‘12’,‘11’,‘11’,‘12’,‘44’,‘44’].chunk{|s|s}.map(&:last)
#=> [[“11”], [“12”, “12”, “12”], [“11”, “11”], [“12”], [“44”, “44”]]

i didnt got it working with slice_before

Hans M. wrote in post #1145556:

are you sure you want slice_before?

[‘11’,‘12’,‘12’,‘12’,‘11’,‘11’,‘12’,‘44’,‘44’].chunk{|s|s}.map(&:last)
#=> [[“11”], [“12”, “12”, “12”], [“11”, “11”], [“12”], [“44”, “44”]]

i didnt got it working with slice_before

Actually the example from the doc
(Module: Enumerable (Ruby 2.1.1))
made me think, this problem also possible in the same way. I tried it
some more ways also. But didn’t get any way.

a = [0, 2, 3, 4, 6, 7, 9]
prev = a[0]
p a.slice_before { |e|
prev, prev2 = e, prev
prev2 + 1 != e
}.map { |es|
es.length <= 2 ? es.join(“,”) : “#{es.first}-#{es.last}”
}.join(“,”)
#=> “0,2-4,6,7,9”

On Friday, 9 May 2014 7:29 PM, Robert K.
[email protected] wrote
On Fri, May 9, 2014 at 12:52 PM, Arup R.

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 R.

On Fri, May 9, 2014 at 12:52 PM, Arup R.
[email protected] 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 ?

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

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 R.
On Friday, 9 May 2014 9:32 PM, Abinoam Jr. [email protected] 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 R.

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 R.