Skip to content

Instantly share code, notes, and snippets.

@dbrady
Created March 12, 2012 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dbrady/2025496 to your computer and use it in GitHub Desktop.
Save dbrady/2025496 to your computer and use it in GitHub Desktop.
pattern for maps that take n-dimensional inputs and yield m-dimensional inputs
# Draw day labels, e.g. "Mon 1/30", "Tue 1/31", "Wed 2/1" etc.
day_labels = (0...DAYS_PER_WEEK).map {|d| (start_date + d).strftime("%a %-m/%-d")}
# HEY GISTERS LOOK HERE: Okay, I have a loop that iterates 0 to
# 6, and I need this for the day_label in question, but I *also*
# need to know the x-coordinate at which to draw the label. What
# I would like in this SPECIFIC case, is a loop construct that
# somehow yields the day_label and x-coordinate, perhaps as a
# pair, which I guess I could do with a map. But in general I'm
# looking for a loop construct that accepts n-dimensional inputs
# (e.g. arrays of 1-element) and emits m-dimensional outputs
# (e.g. arrays of 3-elements).
(0...DAYS_PER_WEEK).each do |i|
x = (TODO_COLUMNS+i) * COLUMN_WIDTH
text_box day_labels[i], at: [x,PAGE_HEIGHT], height: HEADER_HEIGHT, width: COLUMN_WIDTH, align: :center, valign: :center, style: :bold
end
@nz
Copy link

nz commented Mar 12, 2012

But in general I'm looking for a loop construct that accepts n-dimensional inputs (e.g. arrays of 1-element) and emits m-dimensional outputs (e.g. arrays of 3-elements).

Array#zip might be convinced to do your bidding here.

a = [1, 2, 3]
b = [:a, :b, :c]

a.zip(b)
# => [[1, :a], [2, :b], [3, :c]]

a.zip(b).each { |foo, bar| puts "#{foo} - #{bar}" }
#1 - a
#2 - b
#3 - c
# => [[1, :a], [2, :b], [3, :c]]

@dbrady
Copy link
Author

dbrady commented Mar 13, 2012

So this is the answer I was looking for but I don't know if it's really any better:

  day_labels.map.with_index {|label, i| [label, (TODO_COLUMNS+i)*COLUMN_WIDTH]}.each do |label, x|
    text_box label, at: [x,PAGE_HEIGHT], height: HEADER_HEIGHT, width: COLUMN_WIDTH, align: :center, valign: :center, style: :bold
  end

@nz
Copy link

nz commented Mar 13, 2012

Yeah, not too much difference — Array#zip probably wins in my book since it lets you collect and validate your inputs separately.

day_labels = (0...DAYS_PER_WEEK).map { |d| (start_date + d).strftime("%a   %-m/%-d") }
x_offsets  = (0...DAYS_PER_WEEK).map { |d| (TODO_COLUMNS+d)*COLUMN_WIDTH }

day_labels.zip(x_offsets).each do |label, x|
  text_box_with_label_at(label, x)
end

Plus another sneaky refactoring. Because I have a problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment