Frage

Ich weiß, dies ist wahrscheinlich tot ist einfach, aber ich habe einige Daten bekam, wie diese in einer Datei:

Artichoke

Green Globe, Imperial Star, Violetto

24" deep

Beans, Lima

Bush Baby, Bush Lima, Fordhook, Fordhook 242

12" wide x 8-10" deep

, dass ich möchte in der Lage sein, zu formatieren, in einem netten TSV Art der Tabelle etwas wie folgt aussehen:

    Name  | Varieties    | Container Data
----------|------------- |-------
some data here nicely padded with even spacing and right aligned text 
War es hilfreich?

Lösung

Dies ist ein einigermaßen vollständiges Beispiel, dass die folgende

übernimmt
  • Die Liste der Produkte wird in einer Datei namens veg.txt
  • Ihre Daten werden über drei Zeilen pro Datensatz mit den Feldern in aufeinander folgenden Zeilen angeordnet

Ich bin ein bisschen ein Noob zu den Schienen so gibt es zweifellos besser und elegante Art und Weise, dies zu tun

#!/usr/bin/ruby

class Vegetable

  @@max_name ||= 0  
  @@max_variety ||= 0  
  @@max_container ||= 0  

  attr_reader :name, :variety, :container

  def initialize(name, variety, container)
    @name = name
    @variety = variety
    @container = container  

    @@max_name = set_max(@name.length, @@max_name)  
    @@max_variety = set_max(@variety.length, @@max_variety)  
    @@max_container = set_max(@container.length, @@max_container)
  end

  def set_max(current, max)
    current > max ? current : max
  end

  def self.max_name  
    @@max_name  
  end  

  def self.max_variety  
    @@max_variety  
  end  

  def self.max_container()  
    @@max_container  
  end  

end

    products = []


    File.open("veg.txt") do | file|

      while name = file.gets
        name = name.strip
        variety = file.gets.to_s.strip
        container = file.gets.to_s.strip
        veg = Vegetable.new(name, variety, container)
        products << veg
      end
    end

    format="%#{Vegetable.max_name}s\t%#{Vegetable.max_variety}s\t%#{Vegetable.max_container}s\n"
    printf(format, "Name", "Variety", "Container")
    printf(format, "----", "-------", "---------")
    products.each do |p|
        printf(format, p.name, p.variety, p.container)
    end

Die folgende Beispieldatei

Artichoke
Green Globe, Imperial Star, Violetto
24" deep
Beans, Lima
Bush Baby, Bush Lima, Fordhook, Fordhook 242
12" wide x 8-10" deep
Potatoes
King Edward, Desiree, Jersey Royal
36" wide x 8-10" deep

Produziert die folgende Ausgabe

       Name                                      Variety                Container
       ----                                      -------                ---------
  Artichoke         Green Globe, Imperial Star, Violetto                 24" deep
Beans, Lima Bush Baby, Bush Lima, Fordhook, Fordhook 242    12" wide x 8-10" deep
   Potatoes           King Edward, Desiree, Jersey Royal    36" wide x 8-10" deep

Andere Tipps

Versuchen Sie String#rjust(width) :

"hello".rjust(20)           #=> "               hello"

Ich schrieb ein Juwel zu tun genau das: http://tableprintgem.com

Niemand hat die „coolsten“ / kompakteste Weise erwähnt - den % Operator - zum Beispiel: "%10s %10s" % [1, 2]. Hier ist ein Code:

xs = [
  ["This code", "is", "indeed"],
  ["very", "compact", "and"],
  ["I hope you will", "find", "it helpful!"],
]
m = xs.map { |_| _.length }
xs.each { |_| _.each_with_index { |e, i| s = e.size; m[i] = s if s > m[i] } }
xs.each { |x| puts m.map { |_| "%#{_}s" }.join(" " * 5) % x }

Gibt:

      This code          is          indeed
           very     compact             and
I hope you will        find     it helpful!

Hier ist der Code aus mehr lesbar:

max_lengths = xs.map { |_| _.length }
xs.each do |x|
  x.each_with_index do |e, i|
    s = e.size
    max_lengths[i] = s if s > max_lengths[i]
  end
end
xs.each do |x|
  format = max_lengths.map { |_| "%#{_}s" }.join(" " * 5)
  puts format % x
end

ein weiteres Juwel: https://github.com/visionmedia/terminal-table Terminal Tabelle ist ein schneller und einfacher, aber reich an Funktionen ASCII-Tabelle Generator in Ruby geschrieben.

Ich habe eine kleine Funktion einen 2D-Array als Tabelle zu drucken. Jede Zeile muss die gleiche Anzahl von Spalten für diese zu arbeiten. Es ist auch einfach auf Ihre Bedürfnisse zu optimieren.

def print_table(table)
  # Calculate widths
  widths = []
  table.each{|line|
    c = 0
    line.each{|col|
      widths[c] = (widths[c] && widths[c] > col.length) ? widths[c] : col.length
      c += 1
    }
  }
  # Indent the last column left.
  last = widths.pop()
  format = widths.collect{|n| "%#{n}s"}.join(" ")
  format += " %-#{last}s\n"
  # Print each line.
  table.each{|line|
    printf format, *line
  }
end

Kernel.sprintf sollten Sie beginnen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top