HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Ruby: refactor simple string method for aligning DSV text

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simplemethodtextaligningdsvforrubyrefactorstring

Problem

GOAL:

  • Accept DSV strings where the delimiter may consist of more than one character



  • Accept DSV strings where there are no embedded delimiters



  • Output text with no modification to the source string other than aligning custom delimiter with optional padding



QUESTION:

  • Anyone have a re-factor or stylistic enhancement or two?



CODE:

```
module DreftymacAddon
module String
###
def dsvpretty(delim=';;',padd='')
sout = ""
asizes = []
alines = self.to_s.split(/[\x0a\x0d]/)
alines.each{|currline|
currline.split(delim).each_with_index{|currfld,icc|
asizes[icc] = [asizes[icc].to_i,currfld.length].max()
}
}
alines.each{|currline|
next if currline.strip == ''
atemp = []
currline.split(delim).each_with_index{|currfld,icc|
atemp
end
end

class String
include DreftymacAddon::String
end

### String.new().dsvpretty ;; example usage
##{
if(1000!=0);
vout = %Q[
LNAME|FNAME|AMOUNT|AGE|NATION|PLATFORM
Rodriguez|Johan|30.00|58|uk|windows_xp
Raynor|Coty|40.00|14|uk|redhat
Bruen|Jackie|30.00|17|uk|ubuntu
Breitenberg|Waldo|20.00|14|canada|mac_osx
Collier|Lucy|30.00|22|canada|windows_vista
Blick|Emmett|30.00|59|canada|knoppix
Schroeder|Myrtis|10.00|29|uk|knoppix
Rodriguez|Ashtyn|20.00|22|uk|mac_osx
Leuschke|Sigmund|40.00|21|france|redhat
Fahey|Cassidy|40.00|29|canada|knoppix
]

puts vout.dsvpretty('|','')
=begin
LNAME |FNAME |AMOUNT|AGE|NATION|PLATFORM
Rodriguez |Johan |30.00 |58 |uk |windows_xp
Raynor |Coty |40.00 |14 |uk |redhat
Bruen |Jackie |30.00 |17 |uk |ubuntu
Breitenberg|Waldo |20.00 |14 |canada|mac_osx
Collier |Lucy |30.00 |22 |canada|windows_vista
Blick |Emmett |30.00 |59 |canada|knoppix
Schroeder |Myrtis |10.00 |29 |uk |knoppix
Rodriguez |Ashtyn |20.00 |22 |uk |mac_osx

Solution

Some notes:

  • include DreftymacAddon::String. Monkeypatching common classes is always controversial, but in this case I wouldn't do it, it's not a general enough abstraction.



  • As always, I'd recommend using functional style with Ruby (if you check my other answers in this site, it's all I do ;-)) unless you have a very good reason not to. No sout = "", asize = [], each, array[key] = value, += and other statements, use expressions.



  • dsvpretty(delim=';;',padd=''). This kind of signature is problematic, if you want to set padd you are forced to set also delim when you wanted to keep the default value. Use an options hash instead. Note that finally Ruby 2.0 provides keyword arguments.



  • each_with_index{|currfld,icc|. Let the block breathe, and don't forget spaces after commas: each_with_index { |currfld, icc|. More on idiomatic Ruby.



I'd write:

module DreftymacAddon
  def self.dsv_pretty(string, options = {})
    options = {:delim => ";", :padding => ""}.merge(options)
    rows = string.strip.split(/\n/).map { |line| line.strip.split(options[:delim]) }
    columns_max_width = rows.map { |row| row.map(&:size) }.transpose.map(&:max)
    columns_separator = options[:padding] + options[:delim] + options[:padding]

    rows.map do |row|
      row.zip(columns_max_width).map do |cell, column_max_width|
        cell.ljust(column_max_width)
      end.join(columns_separator)
    end.join("\n")
  end
end

puts DreftymacAddon::dsv_pretty(vout, :delim => '|', :padding => " ")

Code Snippets

module DreftymacAddon
  def self.dsv_pretty(string, options = {})
    options = {:delim => ";", :padding => ""}.merge(options)
    rows = string.strip.split(/\n/).map { |line| line.strip.split(options[:delim]) }
    columns_max_width = rows.map { |row| row.map(&:size) }.transpose.map(&:max)
    columns_separator = options[:padding] + options[:delim] + options[:padding]

    rows.map do |row|
      row.zip(columns_max_width).map do |cell, column_max_width|
        cell.ljust(column_max_width)
      end.join(columns_separator)
    end.join("\n")
  end
end

puts DreftymacAddon::dsv_pretty(vout, :delim => '|', :padding => " ")

Context

StackExchange Code Review Q#25974, answer score: 5

Revisions (0)

No revisions yet.