how to make a variable based on array length and member value

Discussion in 'Ruby' started by Catsquotl, Jun 28, 2009.

  1. Catsquotl

    Catsquotl Guest

    Hi

    I have an array full_array[] of an arbitrary number of transaction objects.
    within the transaction is a Date member..

    From the array I have created a new array years[].uniq! based on the
    Date.year members

    what id like to do is take the new arrays members and use them as names
    for variables..

    Say the array holds members for 2007, 2008, 2009
    i`d like to iterate through the full_array and map all members from 2008
    in an array.

    my options are creating an array based on years.length where each member
    holds all transactions from a specific year.

    or iterate through the members of years and create an array based on the
    value or index of years..

    I can`t seem to think of the logic to accomplish this..

    Any ideas?

    Eelco
    Catsquotl, Jun 28, 2009
    #1
    1. Advertising

  2. Catsquotl

    Ian Hobson Guest

    Catsquotl wrote:
    > Hi
    >
    > I have an array full_array[] of an arbitrary number of transaction
    > objects.
    > within the transaction is a Date member..
    >
    > From the array I have created a new array years[].uniq! based on the
    > Date.year members
    >
    > what id like to do is take the new arrays members and use them as
    > names for variables..
    >
    > Say the array holds members for 2007, 2008, 2009
    > i`d like to iterate through the full_array and map all members from
    > 2008 in an array.
    >
    > my options are creating an array based on years.length where each
    > member holds all transactions from a specific year.
    >
    > or iterate through the members of years and create an array based on
    > the value or index of years..
    >
    > I can`t seem to think of the logic to accomplish this..
    >
    > Any ideas?
    >

    Build up a suite of tests and the code in parallel, like this.

    1) Think of a very simple case that isn't yet covered by your code.
    Start with a very simple cases, and proceed to edge cases and
    pathological cases.

    2) Write a new test to run your code and test the result, and run it. It
    will fail, because you HAVE NOT YET WRITTEN THE CODE. (If it doesn't
    fail, you have made a mistake somewhere).

    3) Alter your code to pass the new test and all of the old ones. Only
    when this is the case, may you proceed to stage 4.

    4) Improve you code in some small way - Remove duplicate code, repair a
    bad choice of variable names etc.

    5) After each improvement, Rerun all the tests. If any fail, you
    introduced an error. Fix before proceeding.

    6) When the all pass and your code is nice and clean, save code (and
    tests) to the version control system.

    7) If the code is not yet complete, go to step 1.

    The key is to go in really tiny baby steps at stages 1 and 4, and to
    push stage 4 until you have really nice code you would be proud to show
    anyone. Note - you are testing for anything that might break/be broken,
    not aiming for 100% code coverage.

    You will find that defining the tests will clarify your thinking about
    what is required. Stage 4 means the code remains clean and easy to
    modify. The test suite will stop you introducing errors into your code
    later.

    When you are done, you have nice code, that you can demonstrate is correct.

    Regards

    Ian
    Ian Hobson, Jun 28, 2009
    #2
    1. Advertising

  3. Catsquotl wrote:
    > I have an array full_array[] of an arbitrary number of transaction
    > objects.
    > within the transaction is a Date member..
    >
    > From the array I have created a new array years[].uniq! based on the
    > Date.year members
    >
    > what id like to do is take the new arrays members and use them as names
    > for variables..
    >
    > Say the array holds members for 2007, 2008, 2009
    > i`d like to iterate through the full_array and map all members from 2008
    > in an array.


    Sounds like what you want is a Hash, not an Array. Something like:

    year_to_members = {}
    members.each do |mem|
    y = mem.date.year
    year_to_members[y] ||= []
    year_to_members[y] << mem
    end

    p year_to_members[2009]
    # this prints an array containing elememnts where date.year == 2009

    As others will probably point out, this pattern can be simplified a bit.
    But hopefully it's clear enough as a starting point.

    The fundamental point is, you don't want to create "names of variables"
    for each year - even though that is technically possible, as others may
    also point out. The right thing to do is to build a Hash, which is an
    object which associates a key (a year number) with a value (an array of
    transaction objects).

    HTH,

    Brian.
    --
    Posted via http://www.ruby-forum.com/.
    Brian Candler, Jun 29, 2009
    #3
  4. 2009/6/29 Brian Candler <>:
    > Catsquotl wrote:


    >> Say the array holds members for 2007, 2008, 2009
    >> i`d like to iterate through the full_array and map all members from 2008
    >> in an array.

    >
    > Sounds like what you want is a Hash, not an Array. Something like:


    > As others will probably point out, this pattern can be simplified a bit.


    Since you asked... :)

    year_to_members = Hash.new {|h,k| h[k] = []}

    members.each do |mem|
    year_to_members[mem.date.year] << mem
    end

    > The fundamental point is, you don't want to create "names of variables"
    > for each year - even though that is technically possible, as others may
    > also point out. The right thing to do is to build a Hash, which is an
    > object which associates a key (a year number) with a value (an array of
    > transaction objects).


    100% agree. It is definitively a bad idea to create variables with
    the year in their name.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Jun 29, 2009
    #4
  5. Hi --

    On Sun, 28 Jun 2009, Catsquotl wrote:

    > Hi
    >
    > I have an array full_array[] of an arbitrary number of transaction objects.
    > within the transaction is a Date member..
    >
    > From the array I have created a new array years[].uniq! based on the
    > Date.year members
    >
    > what id like to do is take the new arrays members and use them as names for
    > variables..
    >
    > Say the array holds members for 2007, 2008, 2009
    > i`d like to iterate through the full_array and map all members from 2008 in
    > an array.
    >
    > my options are creating an array based on years.length where each member
    > holds all transactions from a specific year.
    >
    > or iterate through the members of years and create an array based on the
    > value or index of years..
    >
    > I can`t seem to think of the logic to accomplish this..


    You could use group_by (if you've got Ruby 1.9 or a 1.9-flavored 1.8):

    full_array.group_by {|transaction| transaction.date.year }

    That will give you a hash whose keys are the years and whose values
    are arrays of transaction objects, one such array per year-key.


    David

    --
    David A. Black / Ruby Power and Light, LLC
    Ruby/Rails consulting & training: http://www.rubypal.com
    Now available: The Well-Grounded Rubyist (http://manning.com/black2)
    "Ruby 1.9: What You Need To Know" Envycasts with David A. Black
    http://www.envycasts.com
    David A. Black, Jun 29, 2009
    #5
  6. Catsquotl

    Catsquotl Guest

    David A. Black schreef:
    >
    > You could use group_by (if you've got Ruby 1.9 or a 1.9-flavored 1.8):
    >
    > full_array.group_by {|transaction| transaction.date.year }
    >
    > That will give you a hash whose keys are the years and whose values
    > are arrays of transaction objects, one such array per year-key.
    >
    >
    > David
    >

    Thanks for the reply..(Robert, Brian also)
    As a matter of fact I installed 1.9 last week awaiting the arrival of
    the well-grounded rubyist which should be sometime tomorrow

    Eelco
    Catsquotl, Jun 29, 2009
    #6
  7. Catsquotl

    Catsquotl Guest

    Ian Hobson schreef:
    > Build up a suite of tests and the code in parallel, like this.
    >
    > 1) Think of a very simple case that isn't yet covered by your code.
    > Start with a very simple cases, and proceed to edge cases and
    > pathological cases.
    >
    > 2) Write a new test to run your code and test the result, and run it. It
    > will fail, because you HAVE NOT YET WRITTEN THE CODE. (If it doesn't
    > fail, you have made a mistake somewhere).
    >
    > 3) Alter your code to pass the new test and all of the old ones. Only
    > when this is the case, may you proceed to stage 4.
    >
    > 4) Improve you code in some small way - Remove duplicate code, repair a
    > bad choice of variable names etc.
    >
    > 5) After each improvement, Rerun all the tests. If any fail, you
    > introduced an error. Fix before proceeding.
    >
    > 6) When the all pass and your code is nice and clean, save code (and
    > tests) to the version control system.
    >
    > 7) If the code is not yet complete, go to step 1.
    >
    > The key is to go in really tiny baby steps at stages 1 and 4, and to
    > push stage 4 until you have really nice code you would be proud to show
    > anyone. Note - you are testing for anything that might break/be broken,
    > not aiming for 100% code coverage.
    >
    > You will find that defining the tests will clarify your thinking about
    > what is required. Stage 4 means the code remains clean and easy to
    > modify. The test suite will stop you introducing errors into your code
    > later.
    >
    > When you are done, you have nice code, that you can demonstrate is correct.
    >
    > Regards
    >
    > Ian

    Hi Ian,

    As I am a relative beginner do you know any sites/articles/tutorials on
    test driven development?
    All I could find was sites on the benefits of tdd but not a tutorial
    within the ruby language.. found a few in Java

    I have manually tested all classes I write until now which is a bit
    tedious and time consuming..

    I had a quick look at the test/unit Rdocs but am not quite certain on
    how to use them

    Eelco
    Catsquotl, Jun 29, 2009
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Adam Warner

    Flexible array member + variable length array

    Adam Warner, Feb 3, 2005, in forum: C Programming
    Replies:
    10
    Views:
    793
    S.Tobias
    Feb 10, 2005
  2. Peng Yu
    Replies:
    3
    Views:
    1,075
    Simon Forman
    Sep 21, 2009
  3. Tom
    Replies:
    3
    Views:
    207
    salsablr
    Dec 20, 2004
  4. Tuan  Bui
    Replies:
    14
    Views:
    470
    it_says_BALLS_on_your forehead
    Jul 29, 2005
  5. TeknoShock
    Replies:
    1
    Views:
    157
Loading...

Share This Page