В "Programming Elixir" book by Dave Thomas есть аналогичный к чему вам нужно заниматься:
написать код для форматирования данных в столбцы, как на выходе образца в начале главы:
# | Created at | Title
-----+----------------------+--------------------------------------------------
2722 | 2014-08-27T04:33:39Z | Added first draft of File.mv for moving files aro
2728 | 2014-08-29T14:28:30Z | Should elixir (and other applications) have stick
-----+----------------------+--------------------------------------------------
и есть a place where readers can post their solutions to this exercise, где вы можете найти и выбрать то, что костюмы вы. Вам нужно будет модифицировать свой код, чтобы заставить его работать с вашей структурой входных данных (массив массивов, а значит, и с матрицей), но это должно быть легко. Если у вас есть проблемы, просто спросите.
BTW вот мое решение, которое я написал, прочитав книгу:
defmodule Issues.TableFormatter do
import Enum, only: [map: 2, max: 1, zip: 2, join: 2]
@header ~w(number created_at title)
@header_column_separator "-+-"
# TODO: Refactor; try to find more uses for stdlib functions
def print_table(rows, header \\ @header) do
table = rows |> to_table(header)
header = header |> map(&String.Chars.to_string/1) # the headers needs now to be a string
columns_widths = [header | table] |> columns_widths
hr = for _ <- 1..(length(header)), do: "-"
hr |> print_row(columns_widths, @header_column_separator)
header |> print_row(columns_widths)
hr |> print_row(columns_widths, @header_column_separator)
table |> map &(print_row(&1, columns_widths))
hr |> print_row(columns_widths, @header_column_separator)
end
def to_table(list_of_dicts, header) do
list_of_dicts
|> select_keys(header)
|> map(fn (dict) ->
dict
|> Dict.values
|> map(&String.Chars.to_string/1)
end)
end
def columns_widths(table) do
table
|> Matrix.transpose
|> map(fn (cell) ->
cell
|> map(&String.length/1)
|> max
end)
end
def select_keys(dict, keys) do
for entry <- dict do
{dict1, _} = Dict.split(entry, keys)
dict1
end
end
def print_row(row, column_widths, separator \\ " | ") do
padding = separator |> String.to_char_list |> List.first # Hack
IO.puts row
|> zip(column_widths)
|> map(fn ({ cell, column_width }) ->
String.ljust(cell, column_width, padding)
end)
|> join(separator)
end
end
Лечить все это как вдохновение не прямое решение вашей проблемы. Это также может быть намного больше того, что ваши потребности, но возможность быстро форматировать некоторые табличные данные в общем виде и печатать их в вашем терминале может быть очень удобна в будущем для вас.
Спасибо, Патрик, это действительно приятное решение :) – b73
В случае, если кому-то интересно, я переработал этот код на https://gist.github.com/ivan/dc26e349de6f1693c1c77355858564, чтобы 1) вернуть iodata 2) not pad последний столбец 3) не разбивает VM на 0 строк –