سؤال

أعرف أن هذا قد يكون ميتة بسيطة ، ولكن لدي بعض البيانات مثل هذا في ملف واحد:

Artichoke

Green Globe, Imperial Star, Violetto

24" deep

Beans, Lima

Bush Baby, Bush Lima, Fordhook, Fordhook 242

12" wide x 8-10" deep

أود أن تكون قادرة على تنسيق إلى لطيفة TSV نوع من الجدول ، أن ننظر بشيء من هذا القبيل:

    Name  | Varieties    | Container Data
----------|------------- |-------
some data here nicely padded with even spacing and right aligned text 
هل كانت مفيدة؟

المحلول

هذا هو المعقول سبيل المثال الكامل الذي يفترض التالية

  • قائمة المنتجات الواردة في ملف يسمى veg.txt
  • الخاص بك يتم ترتيب البيانات عبر ثلاثة خطوط في سجل مع الحقول على التوالي خطوط

أنا قليلا من مستجد على القضبان لذلك هناك بلا شك أفضل وأكثر أناقة الطرق للقيام بذلك

#!/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

نموذج ملف

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

أنتجت الإخراج التالي

       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

نصائح أخرى

String#rjust(width) :

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

وكتبت جوهرة لتفعل بالضبط هذا: http://tableprintgem.com

لا أحد قد ذكر "أروع" / الطريقة الأكثر المدمجة - باستخدام مشغل % - على سبيل المثال: "%10s %10s" % [1, 2]. وفيما يلي بعض التعليمات البرمجية:

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 }

ويعطي:

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

وهنا هو رمز جعلها أكثر قابلية للقراءة:

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

وآخر جوهرة: https://github.com/visionmedia/terminal-table الجدول المحطة هو سريعة وبسيطة، لكنها سمة غنية جدول ASCII مولد مكتوب في روبي.

ولدي وظيفة صغيرة لطباعة مجموعة 2D كجدول. يجب أن يكون كل صف نفس عدد الأعمدة لهذا العمل. كما انه من السهل على قرص لاحتياجاتك.

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 يجب ان تحصل على انك بدأته.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top