-1

I have hundreds of arrays that am normalizing for a CSV.

[
  ["foo", "tom", nil,     1,   4, "cheese"],
  ["foo", "tom", "fluffy",nil, 4],
  ["foo", "tom", "fluffy",1, nil],
  ...
]

Currently to make them all equal length i am finding the max length and setting to a value.

rows.each { |row| row[max_index] ||= nil }

this is cool because it makes the array length equal to the new length.

Instead of appending a bunch of nils at the end I needed to append COLUMN_N where N is the index (1-based).

table_rows.each do |row|
  last_index = row.length - 1
  (last_index..max_index).to_a.each { |index| row[index] ||= "COLUMN_#{index+1}" }
end

Which seemed like an awkward way to have a default value that is a function of the index.

3
  • 1
    We'd like to see your attempt at solving this. Without that it looks like you want us to write code for you, which isn't what SO is for. Please read "How to Ask" and the linked pages, "minimal reproducible example" and meta.stackoverflow.com/q/261592/128421, which will help explain what are expected. Commented Feb 13, 2017 at 0:38
  • @theTinMan respect. i'll update my question Commented Feb 13, 2017 at 3:35
  • @theTinMan updated. Commented Feb 13, 2017 at 16:24

3 Answers 3

2

You can't choose a default value for filling elements with []= method. But you can easily do something like this if there aren't other nils that you don't want to replace.

row.each_with_index.map { |item, index| item.nil? ? "column_#{index}": item }
Sign up to request clarification or add additional context in comments.

Comments

2

To get a default value instead of nil you can use fetch:

row = ["foo", "tom", "fluffy", 1, 4]
row.fetch(7) { |i| "COLUMN_#{i + 1}" }
=> "COLUMN_8"

But it won't fill the array for you.

Also see: Can I create an array in Ruby with default values?

Comments

0

This seems like it could work for you.

class Array
  def push_with_default(item, index, &block)
    new_arr = Array.new([self.size + 1, index].max, &block)
    self[index] = item
    self.map!.with_index { |n, i| n.nil? ? new_arr[i] : n }
  end
end

>> array = [1,2,5,9]
[
    [0] 1,
    [1] 2,
    [2] 5,
    [3] 9
]
>> array.push_with_default(2, 10) { |i| "column_#{i}" }
[
    [ 0] 1,
    [ 1] 2,
    [ 2] 5,
    [ 3] 9,
    [ 4] "column_4",
    [ 5] "column_5",
    [ 6] "column_6",
    [ 7] "column_7",
    [ 8] "column_8",
    [ 9] "column_9",
    [10] 2
]

I don't believe a method like this exists on Array already though.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.