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 ] ]

···

--
   Phlip
   http://www.zeroplayer.com/

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

martin

···

On Sat, Mar 7, 2009 at 9:48 PM, Phlip <phlip2005@gmail.com> wrote:

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 ] ]

Phlip wrote:

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 ] ]

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

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] }

···

--
   Phlip

class Fixnum
  def to_a
     [self, self]
  end
end

:slight_smile:

martin

···

On Sun, Mar 8, 2009 at 3:43 AM, Phlip <phlip2005@gmail.com> wrote:

Ktx! Now, on to Round Two!

What if the array were even _more_ ragged??

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

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

^ manveru

···

On Sun, Mar 8, 2009 at 7:13 AM, Phlip <phlip2005@gmail.com> wrote:

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\] \}

--
Phlip

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

Solidarity,
lasitha.

···

On Sun, Mar 8, 2009 at 3:43 AM, Phlip <phlip2005@gmail.com> wrote:

Ktx! Now, on to Round Two!

What if the array were even _more_ ragged??

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

<snip>

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 ] ]

Martin DeMello wrote:

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:

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?

···

--
   Phlip

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;).

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

···

--
   Phlip

Indeed (:

martin

···

On Sun, Mar 8, 2009 at 5:38 AM, Phlip <phlip2005@gmail.com> wrote:

Martin DeMello wrote:

class Fixnum
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?

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], ...]

···

On Sun, Mar 8, 2009 at 10:38 PM, Phlip <phlip2005@gmail.com> wrote:
         ~~~~~~~~~~~~~~~~

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