Forum: Ruby Need help on Enumerable#slice_before

249c7fd851c5c5ac5a1abdb756472ae1?d=identicon&s=25 Arup Rakshit (my-ruby)
on 2014-05-09 12:53
(Received via mailing list)
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 Rakshit
D9ebdcb66f1583378e6f72155db507e2?d=identicon&s=25 Hans Mackowiak (hanmac)
on 2014-05-09 14:52
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
249c7fd851c5c5ac5a1abdb756472ae1?d=identicon&s=25 Arup Rakshit (my-ruby)
on 2014-05-09 15:44
Hans Mackowiak 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
(http://www.ruby-doc.org/core-2.1.1/Enumerable.html...)
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"
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2014-05-09 16:00
(Received via mailing list)
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 ?

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
249c7fd851c5c5ac5a1abdb756472ae1?d=identicon&s=25 Arup Rakshit (my-ruby)
on 2014-05-10 10:03
(Received via mailing list)
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
09a32175057418748822c587ac08c429?d=identicon&s=25 Abinoam Jr. (abinoampraxedes_m)
on 2014-05-10 11:07
(Received via mailing list)
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
249c7fd851c5c5ac5a1abdb756472ae1?d=identicon&s=25 Arup Rakshit (my-ruby)
on 2014-05-10 12:35
(Received via mailing list)
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. :-) @Robert made it very
very sweet too. :-)


Regards,
Arup Rakshit
On Friday, 9 May 2014 9:32 PM, Abinoam Jr. <abinoam@gmail.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
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.