Method for Padding an Array in Ruby

Method for padding an array in Ruby

It is killed, because you are entering infinite loop. until a[b-1] will not finish, because when you add nils to the array, you will get:

a == [1, 2, 3, nil, nil, nil, nil, nil, nil, nil]

after few iterations and a[b-1] will be nil, which is falsey. Until will never stop.

About the second question, it is easy to extend existing Array class:

class Array
def padding(i, value=nil)
(i - length).times { self << value }
self
end
end

Result as you expected:

[1,2,3].padding(10)
#=> [1, 2, 3, nil, nil, nil, nil, nil, nil, nil]
[1,2,3].padding(10, "YES")
#=> [1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]

Note the method about modifies existing array (so due to Ruby conventions should be called padding!):

a = [1,2,3]
#=> [1, 2, 3]
a.padding(10, "YES")
#=> [1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]
a
#=> [1, 2, 3, "YES", "YES", "YES", "YES", "YES", "YES", "YES"]

But of course you can easy create the version of the method which doesn't modify. I assumed you want to modify the array, because your original method did it.

Pad an array to be a certain size

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

Creating a Ruby method that pads an Array

In all 3 of your tries, you are returning the original array if desired_size is greater than the original array size. You have that backwards. In other words, you just return instead of padding.

Your first attempt was close. You need to:
1) Fix your conditional check.
2) It's OK to modify the self array, so the more complicated tries are not necessary.
3) Make sure you return self no matter what you do.

By modifying self, not only do you return the modified array, but you also change the array held by the variable test_array. So if you were to do:

test_array = [1, 2, 3]
puts test_array.pad(5, 4).inspect // prints [1, 2, 3, 4, 4]
puts test_array // prints [1, 2, 3, 4, 4]

In Ruby, when a function modifies self, the function name ends with a !, so if you were to write it modifying self, it would be better to name it pad!.

If you want to write it so that it doesn't modify self, you could start with:

array = self.dup

and then do all of your operations on array.

How to pad strings with zeros in Ruby

There is a zero-padding function for Strings in Ruby:

puts acct.rjust(23, '0')

ruby padding an array

Your non-destructive version is actually destructive. What you want is probably this:

def pad(array, min_size, value = nil)
pad!(array.clone, min_size, value)
end

There's no point in implementing the same behaviour twice. Make one bridge off of the other.

Padding a number with zeros

puts 1.to_s.rjust(3, "0")
#=> 001
puts 10.to_s.rjust(3, "0")
#=> 010
puts 100.to_s.rjust(3, "0")
#=> 100

The above code would convert your user.id into a string, then String.rjust() method would consider its length and prefix appropriate number of zeros.

Separate an array of arrays to be passed into a method as multiple objects

What I think you're attempting to do can be accomplished by using the splat operator at the time of method invocation, like such:

hello(*my_array)

Here's a complete example:

def foo(a, *b)
puts a.inspect
puts b.inspect
end

foo(*[[1, 2], [3, 4], [5, 6]])

Prints the following:

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

Edit: Other solution

Now that you've pasted the source my opinion is that the method should be re-written to take a single parameter instead of using the splat operator in the parameters to pull out the first and rest. The reason is that if the length of the multidimensional array changes at runtime you'd be better off pulling out first and rest inside the method so you're not having to use the splat everywhere.

def interleave(args)
a, *args = args
max_length = args.map(&:size).max
padding = [nil]*[max_length-a.size, 0].max
(a+padding).zip(*args).flatten.compact
end

foo([[1, 2], [3, 4], [5, 6]])

Ruby each_slice into sub arrays and set default element values if last sub-array is different size to other sub-arrays

#tap into the resulting array and #fill the last element with the necessary number of false elements:

array = ["1", "b", "0", "7", "9", "2", "a", "a", "5", "7"]
array
.each_slice(3)
.to_a
.tap { |a| a.last.fill(false, a.last.length, 3 - a.last.length) }


Related Topics



Leave a reply



Submit