splitting Array - DRY

J

Josselin

I am presently splitting an array on 4 successives periods of time , is
there a DRYest way to do it, or that's the way to go ? thanks

@ads_id_w1 = advertisings.map {|ad| ad.id if ((ad.valid_until -
ad.created_at) / 86400.0 <= 7)}.compact

@ads_id_w2 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 7) && ((ad.valid_until - ad.created_at) /
86400.0 <= 14)) }.compact

@ads_id_w3 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 14) && ((ad.valid_until - ad.created_at) /
86400.0 <= 21)) }.compact

@ads_id_w4 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 21) && ((ad.valid_until - ad.created_at) /
86400.0 <= 31)) }.compact
 
S

Stefan Rusterholz

Josselin said:
I am presently splitting an array on 4 successives periods of time , is
there a DRYest way to do it, or that's the way to go ? thanks

@ads_id_w1 = advertisings.map {|ad| ad.id if ((ad.valid_until -
ad.created_at) / 86400.0 <= 7)}.compact

@ads_id_w2 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 7) && ((ad.valid_until - ad.created_at) /
86400.0 <= 14)) }.compact

@ads_id_w3 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 14) && ((ad.valid_until - ad.created_at) /
86400.0 <= 21)) }.compact

@ads_id_w4 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 21) && ((ad.valid_until - ad.created_at) /
86400.0 <= 31)) }.compact

class ClassOfAd
def week # may want to name it differently
return nil unless whateverdate.between?(acceptable_start,
acceptable_end) # your call here
((ad.valid_until - ad.created_at).div(604800)) % 4
end
@ads_id = Array.new(4) { [] }
advertisings.each {|ad| @ads_id[ad.week] = ad.id if ad.week }

Depending on your needs that code can be condensed a bit more.

Regards
Stefan
 
J

Josselin

Josselin said:
I am presently splitting an array on 4 successives periods of time , is
there a DRYest way to do it, or that's the way to go ? thanks

@ads_id_w1 = advertisings.map {|ad| ad.id if ((ad.valid_until -
ad.created_at) / 86400.0 <= 7)}.compact

@ads_id_w2 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 7) && ((ad.valid_until - ad.created_at) /
86400.0 <= 14)) }.compact

@ads_id_w3 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 14) && ((ad.valid_until - ad.created_at) /
86400.0 <= 21)) }.compact

@ads_id_w4 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 21) && ((ad.valid_until - ad.created_at) /
86400.0 <= 31)) }.compact

class ClassOfAd
def week # may want to name it differently
return nil unless whateverdate.between?(acceptable_start,
acceptable_end) # your call here
((ad.valid_until - ad.created_at).div(604800)) % 4
end
@ads_id = Array.new(4) { [] }
advertisings.each {|ad| @ads_id[ad.week] = ad.id if ad.week }

Depending on your needs that code can be condensed a bit more.

Regards
Stefan

thanks Stefan, I realize that, too frequently, I am programming Ruby as
C .. not using the OO potential
what's one of the best book about "Programming Ruby, the way it should
be..." ?
I need to practise outside my app dev

note : also found that the 'week' has been already written.. :
(ad.valid_until - ad.created_at) >= 2.weeks
 
R

Robert Klemme

2007/8/20 said:
Josselin said:
I am presently splitting an array on 4 successives periods of time , is
there a DRYest way to do it, or that's the way to go ? thanks

@ads_id_w1 = advertisings.map {|ad| ad.id if ((ad.valid_until -
ad.created_at) / 86400.0 <= 7)}.compact

@ads_id_w2 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 7) && ((ad.valid_until - ad.created_at) /
86400.0 <= 14)) }.compact

@ads_id_w3 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 14) && ((ad.valid_until - ad.created_at) /
86400.0 <= 21)) }.compact

@ads_id_w4 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 21) && ((ad.valid_until - ad.created_at) /
86400.0 <= 31)) }.compact

class ClassOfAd
def week # may want to name it differently
return nil unless whateverdate.between?(acceptable_start,
acceptable_end) # your call here
((ad.valid_until - ad.created_at).div(604800)) % 4
end
@ads_id = Array.new(4) { [] }
advertisings.each {|ad| @ads_id[ad.week] = ad.id if ad.week }

Depending on your needs that code can be condensed a bit more.

Regards
Stefan

thanks Stefan, I realize that, too frequently, I am programming Ruby as
C .. not using the OO potential
what's one of the best book about "Programming Ruby, the way it should
be..." ?
I need to practise outside my app dev

note : also found that the 'week' has been already written.. :
(ad.valid_until - ad.created_at) >= 2.weeks

Basically you need a more generalized version of partition. Maybe
something like this works:

@ads_id = advertisings.inject(Hash.new {|h,k| h[k]=[]}) do |h,ad|
h[(((ad.valid_until - ad.created_at) / 86400 - 1) / 7] << ad.id
h
end

Note, I'm using interger arithmetic to reduce the number of result values.

Kind regards

robert
 
S

Simon Schuster

what's one of the best book about "Programming Ruby, the way it should

the Ruby Cookbook (ISBN: 0-596-52369-6) is really great, as it's
almost entirely working examples with lots of commentary (I learn by
doing/copying/changing), and has a curve that makes it great for
learning and also for later reference. also many of the examples
showcase various gems, which is very helpful for me. The table of
contents makes it very easy for me to find exactly what I'm looking
for. (Chapter 4: Arrays... 4.13: Extracting Portions of Arrays) highly
recommended!

being a beginner to programming in general, Beginning Ruby (ISBN:
1590597664) covers a lot of great information, including a whole big
chapter on documentation, (I wouldn't have thought of looking into
RDoc otherwise!) error handling, debugging and testing... seeing as
how unit testing seems like a big part of ruby, and how I just
wouldn't have thought of looking into it, I find this very helpful as
well. and that's where I am in that book, about halfway, chapter
8/16+appendices, so it'll probably get somewhat advanced. knowing C
already, I don't know if I could recommend it, but perhaps some
foundation-up learning could be helpful. The early stuff shouldn't be
TOO painful, as I'd bet that ruby and C differ pretty early on.
 
J

Josselin

2007/8/20 said:
Josselin wrote:
I am presently splitting an array on 4 successives periods of time , is
there a DRYest way to do it, or that's the way to go ? thanks

@ads_id_w1 = advertisings.map {|ad| ad.id if ((ad.valid_until -
ad.created_at) / 86400.0 <= 7)}.compact

@ads_id_w2 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 7) && ((ad.valid_until - ad.created_at) /
86400.0 <= 14)) }.compact

@ads_id_w3 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 14) && ((ad.valid_until - ad.created_at) /
86400.0 <= 21)) }.compact

@ads_id_w4 = advertisings.map {|ad| ad.id if (((ad.valid_until -
ad.created_at) / 86400.0 > 21) && ((ad.valid_until - ad.created_at) /
86400.0 <= 31)) }.compact

class ClassOfAd
def week # may want to name it differently
return nil unless whateverdate.between?(acceptable_start,
acceptable_end) # your call here
((ad.valid_until - ad.created_at).div(604800)) % 4
end
@ads_id = Array.new(4) { [] }
advertisings.each {|ad| @ads_id[ad.week] = ad.id if ad.week }

Depending on your needs that code can be condensed a bit more.

Regards
Stefan

thanks Stefan, I realize that, too frequently, I am programming Ruby as
C .. not using the OO potential
what's one of the best book about "Programming Ruby, the way it should
be..." ?
I need to practise outside my app dev

note : also found that the 'week' has been already written.. :
(ad.valid_until - ad.created_at) >= 2.weeks

Basically you need a more generalized version of partition. Maybe
something like this works:

@ads_id = advertisings.inject(Hash.new {|h,k| h[k]=[]}) do |h,ad|
h[(((ad.valid_until - ad.created_at) / 86400 - 1) / 7] << ad.id
h
end

Note, I'm using interger arithmetic to reduce the number of result values.

Kind regards

robert

Thanks Robert... I'll put it in my Personal Ruby Cookbook, that's DRYissimo !
 
K

Kaldrenon

the Ruby Cookbook (ISBN: 0-596-52369-6) is really great, as it's
almost entirely working examples with lots of commentary (I learn by
doing/copying/changing), and has a curve that makes it great for
learning and also for later reference.

I have this book too, and I haven't really delved into it, but I can
tell it's definitely worth having. After all, it's an O'Reilly book.
being a beginner to programming in general, Beginning Ruby (ISBN:
1590597664) covers a lot of great information, including a whole big
chapter on documentation, (I wouldn't have thought of looking into
RDoc otherwise!) error handling, debugging and testing... seeing as
how unit testing seems like a big part of ruby, and how I just
wouldn't have thought of looking into it, I find this very helpful as
well. and that's where I am in that book, about halfway, chapter
8/16+appendices, so it'll probably get somewhat advanced. knowing C
already, I don't know if I could recommend it, but perhaps some
foundation-up learning could be helpful. The early stuff shouldn't be
TOO painful, as I'd bet that ruby and C differ pretty early on.

The Pickaxe (the official title is "Programming Ruby - the Pragmatic
Programmers' Guide, 2nd Ed.") is also an excellent resource - highly
informative, well formated code examples, very readable. Might not get
shelved under comedy, but still pretty entertaining, for a programming
book.

If you're LOOKING for comedy, _why's (Poignant) Guide to Ruby is where
it's at. poignantguide.net 'Nuff said.

GL, HF
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top