문제

나는 이것이 아마도 단순하다는 것을 알고 있지만, 하나의 파일에 이와 같은 데이터가 있습니다.

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라는 파일에 포함되어 있습니다.
  • 귀하의 데이터는 연속선의 필드와 함께 레코드 당 3 줄에 배치됩니다.

나는 레일에 약간의 멍청이이므로 의심 할 여지없이 더 좋고 더 우아한 방법이 있습니다.

#!/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터미널 테이블은 빠르고 간단하지만 Ruby로 작성된 풍부한 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