How to un-ragged a 2D array?

Rubies:

Here’s a ragged array:

[ [ 1 ],
[ 2, 3 ],
[ 4 ],
[ 5, 6 ],
[ 7 ],
[ 8 ] ]

How, with the tightest, or most modern, or coolest statements, can we
turn it
into this?

[ [ 1, 1 ],
[ 2, 3 ],
[ 4, 4 ],
[ 5, 6 ],
[ 7, 7 ],
[ 8, 8 ] ]

On Sat, Mar 7, 2009 at 9:48 PM, Phlip [email protected] wrote:

How, with the tightest, or most modern, or coolest statements, can we turn
it into this?

[ [ 1, 1 ],
[ 2, 3 ],
[ 4, 4 ],
[ 5, 6 ],
[ 7, 7 ],
[ 8, 8 ] ]

a.each {|i| i[1] ||= i[0]}

martin

Phlip wrote:

it into this?

[ [ 1, 1 ],
[ 2, 3 ],
[ 4, 4 ],
[ 5, 6 ],
[ 7, 7 ],
[ 8, 8 ] ]

I’m making the following assumptions:
a) we have variable “size” which contains the size of a full subarray
b) subarrays should be filled by repeating the last element until the
subarray
is full.

array = [ [ 1 ],
[ 2, 3 ],
[ 4 ],
[ 5, 6 ],
[ 7 ],
[ 8 ] ]
size = 2
array.map do |subarray|
subarray + [subarray.last] * (size - subarray.size)
end

=> [ [1, 1],

   [2, 3],
   [4, 4],
   [5, 6],
   [7, 7],
   [8, 8] ]

HTH,
Sebastian

On Sun, Mar 8, 2009 at 3:43 AM, Phlip [email protected] wrote:

Ktx! Now, on to Round Two!

What if the array were even more ragged??

[ 1 ,
[ 2, 3 ],
4 ,
[ 5, 6 ],
7 ,
8 ]

class Fixnum
def to_a
[self, self]
end
end

:slight_smile:

martin

Martin DeMello wrote:

def to_a
[self, self]
end
end

:slight_smile:

That thing with the colon and paren, is it Ruby’s operator to
turn-this-monkey-patch-off-if-Fixnum-gets-reused-in-other-modules,
mebbe?

Ktx! Now, on to Round Two!

What if the array were even more ragged??

[   1     ,
  [ 2, 3 ],
    4     ,
  [ 5, 6 ],
    7     ,
    8      ]

The back-story here is: We are asking the user-programmer to enter
either items
or couplets of items. Consider the ActiveRecord DSL, where an :include
=> item,
for example, can be a single item, or an array of items, or a hash of
paired
items, or a hash pointing to an array of items, and so on. AR could
interpret
:include => item by promoting all its scalars to arrays, then running a
simpler
algorithm that only expects arrays.

In my case, the user-programmer can leave the second 1, 4, 7, & 8 out,
as a
convenience, but the algorithm wants this…

[ [ 1, 1 ],
  [ 2, 3 ],
  [ 4, 4 ],
  [ 5, 6 ],
  [ 7, 7 ],
  [ 8, 8 ] ]

…as an internal convenience.

My attempt is needs = needs.map{|x| x.is_a?(Array) ? x : [x,x] }, which
is truly
icky, but might be the shortest way. Besides this!

   needs = needs.map{|x| [x,x].flatten[0..1] }

On Sun, Mar 8, 2009 at 7:13 AM, Phlip [email protected] wrote:

 [ [ 1, 1 ],

   needs = needs.map{|x| [x,x].flatten[0…1] }


 Phlip

needs.map{|e| ([*e] * 2).first(2) }

^ manveru

On Sun, Mar 8, 2009 at 5:38 AM, Phlip [email protected] wrote:

That thing with the colon and paren, is it Ruby’s operator to
turn-this-monkey-patch-off-if-Fixnum-gets-reused-in-other-modules,
mebbe?

Indeed (:

martin

needs.map{|x| [x,x].flatten[0…1] }

needs.map{|e| ([*e] * 2).first(2) }

Look, ma! No .flatten!

That generally might flatten things that deserve to be shapely… (or
ragged;).

On Sun, Mar 8, 2009 at 3:43 AM, Phlip [email protected] wrote:

[ 8, 8 ] ]

needs.map {|x, y| [x, y ||= x] }

Solidarity,
lasitha.

lasitha wrote:

needs.map {|x, y| [x, y ||= x] }

You win! But try just:

needs.map{|x, y| [x, y || x] }

(And would needs.map{|*x| [*x, *x].first(2) } work on Ruby 1.9? 1.8.7?)

However, I ain’t gonna edit my gist just to put it in - you missed the
deadline! (-:

75525’s gists · GitHub

On Sun, Mar 8, 2009 at 10:38 PM, Phlip [email protected] wrote:

lasitha wrote:

needs.map {|x, y| [x, y ||= x] }

You win! But try just:

needs.map{|x, y| [x, y || x] }

Doh! And i was feeling so clever just a minute ago :slight_smile:

(And would needs.map{|*x| [*x, *x].first(2) } work on Ruby 1.9? 1.8.7?)

Neither.

Doesn’t compile on 1.8.7

On 1.9 the splat wraps arrays in another array so we end up with:
[[1, 1], [[2, 3], [2, 3]], [4, 4], …]
~~~~~~~~~~~~~~~~

Best i could manage with explicit use of splat was:
needs.map{|x| [*x] }.each {|x| x[1] ||= x[0] }

Which, combined with Sebastian’s earlier solution, generalises to any
target length:
needs.map{|x| [*x] }.map {|x| x + [x.last] * (legth - x.length) }

However, I ain’t gonna edit my gist just to put it in - you missed the
deadline! (-:

pfft.

cheers :slight_smile:
lasitha