コンソールに情報を出力するスクリプトを生成しています。情報は、値を持つ何らかの統計です。ハッシュのように。
したがって、1つの値の名前は8文字の長さで、もう1つは3です。2つの\ tを使用して情報を出力しているときに、一部の列が正しく配置されていません。
たとえば、出力は次のようになります。
long value name 14
short 12
little 13
tiny 123421
long name again 912421
すべての値を正しく並べてほしい。今私はこれをやっています:
puts "#{value_name} - \t\t #{value}"
長い名前の場合、タブを1つだけ使用すると言うにはどうすればよいですか?それとも別の解決策がありますか?
通常、%10s
うまくフォーマットされるprintf
スキームの一種。
ただし、Rubyをまったく使用していません。そのため、確認する必要があります。
はい、フォーマット付きのprintfがあります。
上記の例は、10文字のスペースで右揃えする必要があります。
列内の最も広いフィールドに基づいて書式設定できます。
printf([port、] format、arg ...)
Sprintfなどのフォーマットに従ってフォーマットされた引数を出力します。最初の引数がIOまたはそのサブクラスのインスタンスである場合、そのオブジェクトにリダイレクトされた印刷。デフォルトは$ stdoutの値です。
最大長が20文字以下であることがわかっている場合:
printf "%-20s %s\n", value_name, value
より動的にしたい場合は、次のようにうまく機能するはずです。
longest_key = data_hash.keys.max_by(&:length)
data_hash.each do |key, value|
printf "%-#{longest_key.length}s %s\n", key, value
end
文字列には、組み込みの ljust があります。
x = {"foo"=>37, "something long"=>42, "between"=>99}
x.each { |k, v| puts "#{k.ljust(20)} #{v}" }
# Outputs:
# foo 37
# something long 42
# between 99
または、タブが必要な場合は、(タブ表示幅を8と仮定して)少し計算して、短い表示関数を書くことができます。
def tab_pad(label, tab_stop = 4)
label_tabs = label.length / 8
label.ljust(label.length + tab_stop - label_tabs, "\t")
end
x.each { |k, v| puts "#{tab_pad(k)}#{v}" }
# Outputs:
# foo 37
# something long 42
# between 99
以前はほとんどバグがありませんでしたが、現在ではprintf構文のほとんどを%演算子で使用できます。
1.9.3-p194 :025 > " %-20s %05d" % ['hello', 12]
=> " hello 00012"
もちろん、事前に計算された幅も使用できます。
1.9.3-p194 :030 > "%-#{width}s %05x" % ['hello', 12]
=> "hello 0000c"
ことを書きました
[[],[],...]
またはハッシュの配列[{},{},...]
コンソールウィンドウには広すぎる列は検出しません
リスト= [[123、 "SDLKFJSLDKFJSLDKFJLSDKJF"]、[123456、 "ffff"]、]
array_maxes
def array_maxes(lists)
lists.reduce([]) do |maxes, list|
list.each_with_index do |value, index|
maxes[index] = [(maxes[index] || 0), value.to_s.length].max
end
maxes
end
end
array_maxes(lists)
# => [6, 24]
puts_arrays_columns
def puts_arrays_columns(lists)
maxes = array_maxes(hashes)
lists.each do |list|
list.each_with_index do |value, index|
print " #{value.to_s.rjust(maxes[index])},"
end
puts
end
end
puts_arrays_columns(lists)
# Output:
# 123, SDLKFJSLDKFJSLDKFJLSDKJF,
# 123456, ffff,
そして別のもの
hashes = [
{ "id" => 123, "name" => "SDLKFJSLDKFJSLDKFJLSDKJF" },
{ "id" => 123456, "name" => "ffff" },
]
hash_maxes
def hash_maxes(hashes)
hashes.reduce({}) do |maxes, hash|
hash.keys.each do |key|
maxes[key] = [(maxes[key] || 0), key.to_s.length].max
maxes[key] = [(maxes[key] || 0), hash[key].to_s.length].max
end
maxes
end
end
hash_maxes(hashes)
# => {"id"=>6, "name"=>24}
puts_hashes_columns
def puts_hashes_columns(hashes)
maxes = hash_maxes(hashes)
return if hashes.empty?
# Headers
hashes.first.each do |key, value|
print " #{key.to_s.rjust(maxes[key])},"
end
puts
hashes.each do |hash|
hash.each do |key, value|
print " #{value.to_s.rjust(maxes[key])},"
end
puts
end
end
puts_hashes_columns(hashes)
# Output:
# id, name,
# 123, SDLKFJSLDKFJSLDKFJLSDKJF,
# 123456, ffff,
編集:長さで考慮されるハッシュキーを修正します。
hashes = [
{ id: 123, name: "DLKFJSDLKFJSLDKFJSDF", asdfasdf: :a },
{ id: 123456, name: "ffff", asdfasdf: :ab },
]
hash_maxes(hashes)
# => {:id=>6, :name=>20, :asdfasdf=>8}
列の列をホワイトリストに登録しますか?
hashes.map{ |h| h.slice(:id, :name) }
# => [
# { id: 123, name: "DLKFJSDLKFJSLDKFJSDF" },
# { id: 123456, name: "ffff" },
#]
将来の参考のために、またこれを見たり見つけたりする人のために... gemを使用してください。 https://github.com/wbailey/command_line_reporter をお勧めします
通常、タブを使用したくない、スペースを使用して、基本的に自分の「列」を設定したい、そうでなければこれらのタイプの問題に遭遇します。