web-dev-qa-db-ja.com

タブの数を指定して、コンソールへの出力を適切にフォーマットします

コンソールに情報を出力するスクリプトを生成しています。情報は、値を持つ何らかの統計です。ハッシュのように。

したがって、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つだけ使用すると言うにはどうすればよいですか?それとも別の解決策がありますか?

53
user130532

通常、%10sうまくフォーマットされるprintfスキームの一種。
ただし、Rubyをまったく使用していません。そのため、確認する必要があります。


はい、フォーマット付きのprintfがあります。
上記の例は、10文字のスペースで右揃えする必要があります。
列内の最も広いフィールドに基づいて書式設定できます。

printf([port、] format、arg ...)

Sprintfなどのフォーマットに従ってフォーマットされた引数を出力します。最初の引数がIOまたはそのサブクラスのインスタンスである場合、そのオブジェクトにリダイレクトされた印刷。デフォルトは$ stdoutの値です。

23
nik

最大長が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
55
Lars Haugseth

文字列には、組み込みの 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
14
Kyle VanderBeek

以前はほとんどバグがありませんでしたが、現在ではprintf構文のほとんどを%演算子で使用できます。

1.9.3-p194 :025 > " %-20s %05d" % ['hello', 12]
 => " hello                00012" 

もちろん、事前に計算された幅も使用できます。

1.9.3-p194 :030 > "%-#{width}s %05x" % ['hello', 12]
  => "hello          0000c" 
10
sergeych

ことを書きました

  • 列幅を自動的に検出します
  • スペースのあるスペース
  • 配列の配列[[],[],...]またはハッシュの配列[{},{},...]
  • コンソールウィンドウには広すぎる列は検出しません

    リスト= [[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"                 },
#]
3
Nate

将来の参考のために、またこれを見たり見つけたりする人のために... gemを使用してください。 https://github.com/wbailey/command_line_reporter をお勧めします

1
Brett Hardin

通常、タブを使用したくない、スペースを使用して、基本的に自分の「列」を設定したい、そうでなければこれらのタイプの問題に遭遇します。

0
ThaDon