문제
나는 이것이 아마도 단순하다는 것을 알고 있지만, 하나의 파일에 이와 같은 데이터가 있습니다.
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 당신을 시작해야합니다.
제휴하지 않습니다 StackOverflow