From: eregontp@... Date: 2016-03-17T10:33:42+00:00 Subject: [ruby-core:74415] [Ruby trunk Feature#12116] `Fixnum#divmod`, `Bignum#divmod` with multiple arguments Issue #12116 has been updated by Benoit Daloze. Nice idea! +1 ---------------------------------------- Feature #12116: `Fixnum#divmod`, `Bignum#divmod` with multiple arguments https://bugs.ruby-lang.org/issues/12116#change-57538 * Author: Tsuyoshi Sawada * Status: Open * Priority: Normal * Assignee: ---------------------------------------- Sometimes, I need to apply `divmod` repeatedly. For example, in order to convert a number expressing seconds into approx year, day, hour, minutes, seconds (approx in the sense of ignoring leap day and leap second), I can repeatedly apply `divmod`: ~~~RUBY seconds = 289342751 minutes, seconds = seconds.divmod(60) # => [4822379, 11] hours, minutes = minutes.divmod(60) # => [80372, 59] days, hours = hours.divmod(24) # => [3348, 20] years, days = days.divmod(365) # => [9, 63] ~~~ so that I get that 289342751 seconds is approx 9 years 63 days 20 hours 59 minutes and 11 seconds. But it is cumbersome to do all that. It would be convenient if `divmod` can take multiple arguments so that the conventional `divmod` is applied from the right-most argument to the left, returning the above result at once: ~~~RUBY 289342751.divmod(365, 24, 60, 60) # => [9, 63, 20, 59, 11] ~~~ In general, when `n` arguments are passed to the proposed `divmod`, an array of `n + 1` elements should be returned. Another use case is nested arrays. Some people tend to express a matrix as a nested array, and try to access the innermost elements using multiple indices. To list the coordinates of the occurrences of `1`, one may do: ~~~RUBY m = [ [1, 0, 0], [0, 1, 0], [0, 0, 1], ] a = [] m.each_with_index do |row, i| row.each_with_index do |e, j| a.push([i, j]) if e == 1 end end a # => [[0, 0], [1, 1], [2, 2]] ~~~ But it is often easier to have a flat array and use `divmod` with it: ~~~RUBY m = [ 1, 0, 0, 0, 1, 0, 0, 0, 1, ] m.each.with_index.select{|e, _| e == 1}.map{|_, i| i.divmod(3)} # => [[0, 0], [1, 1], [2, 2]] ~~~ However, once the nesting achieves another level, it becomes cumbersome. Instead of using a nested array: ~~~RUBY t = [ [ ["a", "b"], ["c", "d"], ], [ ["a", "b"], ["c", "d"], ], ] ~~~ one can keep using a flat array, but that would require repeated application of `divmod` to covert between the flat index and the nested index. The proposed feature would also help in such case. -- https://bugs.ruby-lang.org/ Unsubscribe: