dreeves
dreeves

Reputation: 26932

Pad an array to be a certain size

There's probably a more efficient and more Ruby-ish way to do this:

# Pad array to size n by adding x's. Don't do anything if n <= a.length.
def padleft(a, n, x)
  return a if n <= a.length
  return padleft([x] + a, n, x)
end

What would you suggest?

Upvotes: 17

Views: 13146

Answers (7)

Topher Fangio
Topher Fangio

Reputation: 20667

Here's another fun one-liner to do it:

(non-destructive)

def padleft(a, n, x)
  a.dup.reverse.fill(x, a.length..n-1).reverse
end

(destructive)

def padleft(a, n, x)
  a.reverse.fill(x, a.length..n-1).reverse
end

Upvotes: 1

bronson
bronson

Reputation: 6002

If you're using Rails and want the padding on the right:

[1,2,3,4,5,6].in_groups_of(4)
=> [[1, 2, 3, 4], [5, 6, nil, nil]]

This doesn't come anywhere near answering the question but it's what I ended up needing after visiting this page. Hope it helps someone.

Upvotes: -1

Jikku Jose
Jikku Jose

Reputation: 18804

Perhaps more Rubyish ;)

# Pad array to size n by adding x's. Don't do anything if n <= a.length.
def padleft(a, n, x)
  (n - a.size).times.inject(a) do |array, i|
    array << x
  end
end

Upvotes: 1

DiegoSalazar
DiegoSalazar

Reputation: 13521

FWIW:

def rpad(item, padding, num)
  Array(item).fill padding, Array(item).size, num
end
# rpad "initialize value(s)", 0, 3
# => ["initialize value(s)", 0, 0, 0]

Upvotes: 5

sawa
sawa

Reputation: 168091

Edited due to my misunderstanding of the question. Pervious version of my answer padded from the right side, but the question was asking to do it from the left side. I corrected it accordingly. This is due to naming convention. ljust, rjust are builtin methods for String, and I extended that convention to Array, but that corresponds to padright and padleft, respectively, in the terminology of the question.

Destructive methods

def padleft!(a, n, x)
  a.insert(0, *Array.new([0, n-a.length].max, x))
end
def padright!(a, n, x)
  a.fill(x, a.length...n)
end

It would be more natural to have it defined on Array class:

class Array
  def rjust!(n, x); insert(0, *Array.new([0, n-length].max, x)) end
  def ljust!(n, x); fill(x, length...n) end
end

Non-destructive methods

def padleft(a, n, x)
  Array.new([0, n-a.length].max, x)+a
end
def padright(a, n, x)
  a.dup.fill(x, a.length...n)
end

or

class Array
  def rjust(n, x); Array.new([0, n-length].max, x)+self end
  def ljust(n, x); dup.fill(x, length...n) end
end

Upvotes: 26

the Tin Man
the Tin Man

Reputation: 160551

Using 10 for the length to pad to, and 'x' to be what you're padding to, this pads right:

>> asdf = %w[0 1 2 3 ] #=> ["0", "1", "2", "3"]
>> asdf += (asdf.size < 10) ? ['x'] * (10 - asdf.size) : [] #=> ["0", "1", "2", "3", "x", "x", "x", "x", "x", "x"]

or

>> asdf = (asdf.size < 10) ? ['x'] * (10 - asdf.size) + asdf : asdf #=> ["x", "x", "x", "x", "x", "x", "0", "1", "2", "3"]

to padleft

If it makes sense to you to monkey-patch Array:

class Array
  def pad_right(s, char=nil)
    self + [char] * (s - size) if (size < s)
  end

  def pad_left(s, char=nil)
    (size < s) ? [char] * (s - size) + self : self
  end
end

%w[1 2 3].pad_right(5, 'x') # => ["1", "2", "3", "x", "x"]
%w[1 2 3].pad_left(5, 'x') # => ["x", "x", "1", "2", "3"]

Upvotes: 4

kqnr
kqnr

Reputation: 3596

Using the * operator to repeat a list.

# Pad array to size n by adding x's. Don't do anything if n <= a.length.
def padleft(a, n, x)
  return a if n <= a.length
  return [x] * (n - a.length) + a
end

Upvotes: 2

Related Questions