Previous value in array block

Is this a good way to use a previous value in an array block?

I want to subtract the item(i) from item(i-1) of the array, a and return
a new array of the results. Below is my attempt.

a = [1,3,3,2]
prev_item = 0
b = []

a.each do |item|
  b << item - prev_item
  prev_item = item
end

puts b

=> 1,2,0,-1

I'm thinking there must be a more elegant way of doing this.

thank you!

···

--
Posted via http://www.ruby-forum.com/.

Is this a good way to use a previous value in an array block?

I want to subtract the item(i) from item(i-1) of the array, a and return
a new array of the results. Below is my attempt.

a = [1,3,3,2]
prev_item = 0
b =

a.each do |item|
b << item - prev_item
prev_item = item
end

puts b

=> 1,2,0,-1

I'm thinking there must be a more elegant way of doing this.

to me, your code is elegant enough.
not sure if making code shorter would make it more, so..

a = [1,3,3,2]

=> [1, 3, 3, 2]

a.zip(a.dup.unshift(0)).map{|x,y| x-y}

=> [1, 2, 0, -1]

kind regards -botp

···

On Wed, Jul 29, 2009 at 11:39 AM, Jason Lillywhite<jason.lillywhite@gmail.com> wrote:

Jason Lillywhite wrote:

a = [1,3,3,2]
prev_item = 0
b =

a.each do |item|
  b << item - prev_item
  prev_item = item
end

puts b

=> 1,2,0,-1

Another way could be:

a = [1,3,3,2]
b = [a[0]]

for i in 1...(a.length)
  b << (a[i] - a[i-1])
end

puts b

Not sure if that can be considered elegant though. :slight_smile:

-DR

···

--
Posted via http://www.ruby-forum.com/\.

I want to subtract the item(i) from item(i-1) of the array, a and return
a new array of the results. Below is my attempt.

But, you are doing the opposite :slight_smile:
Anyway, based on your code,

FWIW, here is another one-liner.
Elegant? I don't know.

b = Array.new(a.length){|i| a[i]-a[i-1]}[1..-1].unshift(a[0])

Harry

···

--
A Look into Japanese Ruby List in English

Jason Lillywhite wrote:

Is this a good way to use a previous value in an array block?

I want to subtract the item(i) from item(i-1) of the array, a and return
a new array of the results. Below is my attempt.

a = [1,3,3,2]
prev_item = 0
b =

a.each do |item|
  b << item - prev_item
  prev_item = item
end

puts b

=> 1,2,0,-1

I'm thinking there must be a more elegant way of doing this.

thank you!

I was recently reading through the facets docuementation and so thought I would develop a solution for the OP using the elementwise method that facets supplies. However while other facets methods from enumerable are available, elementwise does not seem to be.

C:\Documents and Settings\Administrator>irb
irb(main):001:0> a=Array.new
=>
irb(main):002:0> a.respond_to?("elementwise")
=> false
irb(main):003:0> a.respond_to?("entropy")
=> false
irb(main):004:0> require "facets"
=> true
irb(main):005:0> a.respond_to?("entropy")
=> true
irb(main):006:0> a.respond_to?("elementwise")
=> false

I am using windows xp, one click Ruby 186-26 and facets 2.5.0.

Can some kind person point out my error?

Thanks

Steve

Never forget: we don't need no stinkin' loops!

x = 2,3,5,8,13
p x.zip( [0] + x ).map{|a,b| a-b}

=> [2, 1, 2, 3, 5]

···

On Jul 28, 10:39 pm, Jason Lillywhite <jason.lillywh...@gmail.com> wrote:

Is this a good way to use a previous value in an array block?

I want to subtract the item(i) from item(i-1) of the array, a and return
a new array of the results. Below is my attempt.

a = [1,3,3,2]
prev_item = 0
b =

a.each do |item|
  b << item - prev_item
  prev_item = item
end

puts b

=> 1,2,0,-1

I'm thinking there must be a more elegant way of doing this.

thank you!
--
Posted viahttp://www.ruby-forum.com/.

Never forget: we don't need no stinkin' loops!

x = 2,3,5,8,13
p x.zip( [0] + x ).map{|a,b| a-b}

=> [2, 1, 2, 3, 5]

···

On Jul 28, 10:39 pm, Jason Lillywhite <jason.lillywh...@gmail.com> wrote:

Is this a good way to use a previous value in an array block?

I want to subtract the item(i) from item(i-1) of the array, a and return
a new array of the results. Below is my attempt.

a = [1,3,3,2]
prev_item = 0
b =

a.each do |item|
  b << item - prev_item
  prev_item = item
end

puts b

=> 1,2,0,-1

I'm thinking there must be a more elegant way of doing this.

thank you!
--
Posted viahttp://www.ruby-forum.com/.

Another way:

irb(main):001:0> a = [10,20,30,40]
irb(main):014:0> b =
=>
irb(main):015:0> a.each_with_index {|x,y| b << (y > 0? (x - a[y-1]): x)}
=> [10, 20, 30, 40]

irb(main):019:0> b
=> [10, 10, 10, 10]

Jesus.

···

On Wed, Jul 29, 2009 at 8:18 AM, Harry Kakueki<list.push@gmail.com> wrote:

I want to subtract the item(i) from item(i-1) of the array, a and return
a new array of the results. Below is my attempt.

But, you are doing the opposite :slight_smile:
Anyway, based on your code,

FWIW, here is another one-liner.
Elegant? I don't know.

b = Array.new(a.length){|i| a[i]-a[i-1]}[1..-1].unshift(a[0])

each_cons seems natural here:

require 'enumerator'

a = [1, 3, 3, 2]
b = a[0, 1]

a.each_cons(2) { |x, y| b << y - x }

Hi --

···

On Wed, 29 Jul 2009, Xavier Noria wrote:

each_cons seems natural here:

require 'enumerator'

a = [1, 3, 3, 2]
b = a[0, 1]

a.each_cons(2) { |x, y| b << y - x }

Here's a 1.9 way, probably guilty of gross wasteage (by creating an
extra new array) but kind of cool:

[0,*a].each_cons(2).map {|x,y| y - x }

David

--
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Q: What's the best way to get a really solid knowledge of Ruby?
A: Come to our Ruby training in Edison, New Jersey, September 14-17!
    Instructors: David A. Black and Erik Kastner
    More info and registration: http://rubyurl.com/vmzN

each_cons seems natural here:

require 'enumerator'

a = [1, 3, 3, 2]
b = a[0, 1]

a.each_cons(2) { |x, y| b << y - x }

and purely functional
( [0] + a ).each_cons( 2 ).map{ |x,y| y -x }
or with Tom's map arity trick implemented
( [0] + a ).map{ | x, y | y - x }

···

On Wed, Jul 29, 2009 at 10:50 AM, Xavier Noria<fxn@hashref.com> wrote:

--
Toutes les grandes personnes ont d’abord été des enfants, mais peu
d’entre elles s’en souviennent.

All adults have been children first, but not many remember.

[Antoine de Saint-Exupéry]

A beauty, sorry did not see it before my post!
Cheers
Robert

···

On Wed, Jul 29, 2009 at 12:56 PM, David A. Black<dblack@rubypal.com> wrote:

Hi --

On Wed, 29 Jul 2009, Xavier Noria wrote:

each_cons seems natural here:

require 'enumerator'

a = [1, 3, 3, 2]
b = a[0, 1]

a.each_cons(2) { |x, y| b << y - x }

Here's a 1.9 way, probably guilty of gross wasteage (by creating an
extra new array) but kind of cool:

[0,*a].each_cons(2).map {|x,y| y - x }

Hi --

···

On Wed, 29 Jul 2009, Robert Dober wrote:

On Wed, Jul 29, 2009 at 10:50 AM, Xavier Noria<fxn@hashref.com> wrote:

each_cons seems natural here:

require 'enumerator'

a = [1, 3, 3, 2]
b = a[0, 1]

a.each_cons(2) { |x, y| b << y - x }

and purely functional
( [0] + a ).each_cons( 2 ).map{ |x,y| y -x }
or with Tom's map arity trick implemented
( [0] + a ).map{ | x, y | y - x }

I don't understand that last one. Is this some kind of override of map
that turns it into each_cons + map?

David

--
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Q: What's the best way to get a really solid knowledge of Ruby?
A: Come to our Ruby training in Edison, New Jersey, September 14-17!
    Instructors: David A. Black and Erik Kastner
    More info and registration: http://rubyurl.com/vmzN

very cool.
thanks for the tip.

kind regards -botp

···

On Wed, Jul 29, 2009 at 8:11 PM, Robert Dober<robert.dober@gmail.com> wrote:

or with Tom's map arity trick implemented
( [0] + a ).map{ | x, y | y - x }

Here's a lisp/scheme inspired approach using inject and with an array
serving as a "cons cell" and first => car and last => cdr:

[1, 3, 3, 2].inject([0, ]) { |memo, elem| [elem, memo.last << (elem
- memo.first)] }.last # => [1, 2, 0, -1]

···

On Wed, Jul 29, 2009 at 8:11 AM, Robert Dober<robert.dober@gmail.com> wrote:

On Wed, Jul 29, 2009 at 10:50 AM, Xavier Noria<fxn@hashref.com> wrote:

each_cons seems natural here:

require 'enumerator'

a = [1, 3, 3, 2]
b = a[0, 1]

a.each_cons(2) { |x, y| b << y - x }

and purely functional
( [0] + a ).each_cons( 2 ).map{ |x,y| y -x }

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Hi --

each_cons seems natural here:

require 'enumerator'

a = [1, 3, 3, 2]
b = a[0, 1]

a.each_cons(2) { |x, y| b << y - x }

and purely functional
( [0] + a ).each_cons( 2 ).map{ |x,y| y -x }
or with Tom's map arity trick implemented
( [0] + a ).map{ | x, y | y - x }

I don't understand that last one. Is this some kind of override of map
that turns it into each_cons + map?

IIRC it was like this

module Enumerable
   method_alias :__map__, map
   def map &blk
      return __map__(&blk) if blk.arity < 2
      each_cons( blk.arity).map(&blk)
   ...

Robert

···

On Wed, Jul 29, 2009 at 2:16 PM, David A. Black<dblack@rubypal.com> wrote:

On Wed, 29 Jul 2009, Robert Dober wrote:

On Wed, Jul 29, 2009 at 10:50 AM, Xavier Noria<fxn@hashref.com> wrote:

David

--
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Q: What's the best way to get a really solid knowledge of Ruby?
A: Come to our Ruby training in Edison, New Jersey, September 14-17!
Instructors: David A. Black and Erik Kastner
More info and registration: http://rubyurl.com/vmzN

--
Toutes les grandes personnes ont d’abord été des enfants, mais peu
d’entre elles s’en souviennent.

All adults have been children first, but not many remember.

[Antoine de Saint-Exupéry]

Hi --

···

On Wed, 29 Jul 2009, Robert Dober wrote:

On Wed, Jul 29, 2009 at 2:16 PM, David A. Black<dblack@rubypal.com> wrote:

Hi --

On Wed, 29 Jul 2009, Robert Dober wrote:

On Wed, Jul 29, 2009 at 10:50 AM, Xavier Noria<fxn@hashref.com> wrote:

each_cons seems natural here:

require 'enumerator'

a = [1, 3, 3, 2]
b = a[0, 1]

a.each_cons(2) { |x, y| b << y - x }

and purely functional
( [0] + a ).each_cons( 2 ).map{ |x,y| y -x }
or with Tom's map arity trick implemented
( [0] + a ).map{ | x, y | y - x }

I don't understand that last one. Is this some kind of override of map
that turns it into each_cons + map?

IIRC it was like this

module Enumerable
  method_alias :__map__, map
  def map &blk
     return __map__(&blk) if blk.arity < 2
     each_cons( blk.arity).map(&blk)
  ...

I confess I don't see the point, but thanks for clarifying.

David

--
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Q: What's the best way to get a really solid knowledge of Ruby?
A: Come to our Ruby training in Edison, New Jersey, September 14-17!
    Instructors: David A. Black and Erik Kastner
    More info and registration: http://rubyurl.com/vmzN

It is cheating, bending Ruby to the needs of the problem. We even had
a discussion if it should use each_cons or each_slice below the hood.

But the point might be, that it might make sense to have things like
map_cons or map_slice
I can only think about Ruby code, writing it, sorry.
Gotta look into Facets for that.

Cheers
Robert

···

On Wed, Jul 29, 2009 at 2:31 PM, David A. Black<dblack@rubypal.com> wrote:

I confess I don't see the point, but thanks for clarifying.

Hi --

···

On Wed, 29 Jul 2009, Robert Dober wrote:

On Wed, Jul 29, 2009 at 2:31 PM, David A. Black<dblack@rubypal.com> wrote:

I confess I don't see the point, but thanks for clarifying.

It is cheating, bending Ruby to the needs of the problem. We even had
a discussion if it should use each_cons or each_slice below the hood.

But the point might be, that it might make sense to have things like
map_cons or map_slice

In 1.9 you get: enumerable.each_cons(x).map ... which has much the
same effect. I don't like the idea of map having a stealth each_cons
in it. Also, defining it for Enumerable won't affect arrays (at least
in MRI), because Array overries map.

David

--
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Q: What's the best way to get a really solid knowledge of Ruby?
A: Come to our Ruby training in Edison, New Jersey, September 14-17!
    Instructors: David A. Black and Erik Kastner
    More info and registration: http://rubyurl.com/vmzN

yes we should not confuse, playing around and changing the language. I
have sometimes the feeling that people get nervous when I do this
"cheating" stuff, but if I meant this to be in Ruby I would say so and
probably at Ruby core. No it is just for the fun and elegance.
R.

···

On Wed, Jul 29, 2009 at 3:20 PM, David A. Black<dblack@rubypal.com> wrote:

Hi --

On Wed, 29 Jul 2009, Robert Dober wrote:

On Wed, Jul 29, 2009 at 2:31 PM, David A. Black<dblack@rubypal.com> wrote:

I confess I don't see the point, but thanks for clarifying.

It is cheating, bending Ruby to the needs of the problem. We even had
a discussion if it should use each_cons or each_slice below the hood.

But the point might be, that it might make sense to have things like
map_cons or map_slice

In 1.9 you get: enumerable.each_cons(x).map ... which has much the
same effect. I don't like the idea of map having a stealth each_cons
in it. Also, defining it for Enumerable won't affect arrays (at least
in MRI), because Array overries map.