1

Is it possible to create an Array from another Array?
Lang: Ruby on Rails

Case

Workers are entitled to fill in their own work hours. Sometimes they forget to do it. This is what I want to tackle. In the end, I want an Array with time codes of periods the worker forgot to register his hours.

timecodes = [201201, 201202, 201203, 201204, 201205, 201206, 201207, 201208, 201209, 201210, 201211, 201212, 201213, 201301, 201302, 201304, 201305, 201306, ...]

Worker works from 201203 to 201209 with us.

timecards = [201203, 201204, 201205, 201207, 201208, 201209]

As you see, he forgot to register 201206.

What I want to do

# Create Array from timecode on start to timecode on end
worked_with_us = [201203, 201204, 201205, 201206, 201207, 201208, 201209]  
   #=> This is the actual problem, how can I automate this?

forgot_to_register = worked_with_us.?????(timecards)
forgot_to_register = worked_with_us - timecards  # Thanks Zwippie
   #=> [201206]

Now I know which period the worker forgot to register his hours.

All together

  1. How can I create an Array from another Array, giving a start and end value?

1 Answer 1

2

You can just subtract arrays with - (minus):

[1, 2, 3] - [1, 3] = [2]

To build an array with years/months, this can be done with a Range, but this only works if you build an array for each year, something like:

months = (2012..2013).map do |year|
  ("#{year}01".."#{year}12").to_a.collect(&:to_i)
end.flatten

  => [201201, 201202, 201203, 201204, 201205, 201206, 201207, 201208, 201209, 201210, 201211, 201212, 201301, 201302, 201303, 201304, 201305, 201306, 201307, 201308, 201309, 201310, 201311, 201312]

And for the function to create those ranges dynamically:

def month_array(year_from, year_to, month_from=1, month_to=12)
  (year_from..year_to).map do |year|
    # Correct from/to months
    mf = year_from == year ? month_from : 1
    mt = year_to == year ? month_to : 12

    (mf..mt).map do |month|
      ("%d%02d" % [year, month]).to_i
    end
  end.flatten
end

Update: You wanted other input parameters for this method, but I hope you can work that out yourself. :)

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, I was totally thinking to complicated! Do you have any ideas on the first issue?
Thank you, I achieved that with (2012..2013).each do |y| { (1..13).each do |p| { timecodes.push "#{y}#{"02d" % p}" } }. I want to create an array based on this array. So I can give the start value and the stop value and create an array from those. Let's say: start = 201210, stop = 201303. The Array should be: worked_with_us = [201210, 201211, 201212, 201213, 201301, 201302, 201303]
Ok, I added a method to do that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.