small medium large xlarge

Dave_gnome_head_isolated_pragsmall
16 Jul 2013, 02:25
Dave Thomas (344 posts)
  • Write a function that takes a list of dqs and prints each on a separate line, centered in a column which is the width of the longest. Make sure it works with UTF characters.

    iex> center(["cat", "zebra", "elephant"])
      cat
     zebra
    elephant
    

A Possible Solution</summary>

defmodule MyString do

  def center(strings) do
    strings 
    |> Enum.map_reduce(0, accumulate_max_length(&1, &2))
    |> center_strings_in_field
    |> Enum.each(IO.puts(&1))
  end

  # We jump through this hoop to avoid calculating the string length twice.
  # Here, we build a tuple containing the length and the string, and
  # nest it in a tuple containing the maximum length seen so far
  defp accumulate_max_length(string, max_length_so_far) do
    l = String.length(string)
    { {string, l}, max(l, max_length_so_far) }
  end

  defp center_strings_in_field({strings, field_width}) do
    strings |> Enum.map(center_one_string(field_width, &1))
  end

  defp center_one_string(field_width, {string, length}) do
    %b[#{String.duplicate(" ", div(field_width - length, 2))}#{string}]
  end
end

MyString.center %w{ cat zebra elephant }

</details>

Mac 128k logic board 96x96_pragsmall
31 Oct 2013, 15:24
Roger Turner (7 posts)

  def center(strings) do
    strings 
    |> center_strings 
    |> Enum.each &IO.puts/1
  end

  def center_strings(strings) do
    max_length = strings |> Enum.map(&String.length/1) |> Enum.max
    in_width = fn (string) ->
      l = String.length string
      div(max_length - l, 2) + l
    end
    strings |> Enum.map &(String.rjust(&1, in_width.(&1)))
  end

Generic-user-small
14 Jan 2014, 01:41
Daniel Ashton (7 posts)
defmodule Binaries do

  import Enum, only: [max: 1, map: 2, each: 2]
  import String, only: [length: 1, duplicate: 2]
  import Kernel, except: [length: 1]

  def center(str_list) do
    max_len = str_list |> map(&(length &1)) |> max
    str_list |> each &(IO.puts duplicate(" ", div(max_len - length(&1), 2)) <> &1)
  end

end
Generic-user-small
16 Jun 2014, 02:51
Luke Imhoff (6 posts)

I found that Erlang has a :string library, but confusingly, there strings are character lists, but since we’re just calling IO.puts and it doesn’t care, you can use :string.centre (note British English spelling even though the docs will say ‘center’ in the description).

defmodule DoubleQuotedStrings do
  def center(list_of_strings) do
    max_length = list_of_strings
                 |> Enum.map(&String.length/1)
                 |> Enum.max
    list_of_strings
    |> Enum.map(&String.to_char_list/1)
    |> Enum.map(&(:string.centre(&1, max_length)))
    |> Enum.map(&IO.puts/1)
  end
end
Generic-user-small
14 Aug 2014, 09:54
Jeremy Ozog (1 post)
  def center(strings) do
    maxlength = strings |> Enum.max_by(&String.length/1) |> String.length
    Enum.map(strings, &(display_padded_string(&1, maxlength)))
  end
  defp display_padded_string(str, maxlength), do: IO.puts String.rjust(str, get_padding(str, maxlength))
  defp get_padding(str, maxlength), do: String.length(str) + div(maxlength-String.length(str), 2)
Generic-user-small
22 Aug 2014, 09:27
Peng Xiang (1 post)

It seems I still don’t get the sprit of functional programming…

defmodule StringList do
  def center string_list do
    max_length = string_list |> Enum.map(&String.length/1) |> Enum.max
    Enum.each string_list, fn str ->
      IO.puts String.rjust str, div(max_length+String.length(str),2)
    end
  end
end

StringList.center ["hello", "world", "Hahahahaha"]
Blacksad-cov_sq_pragsmall
21 Sep 2014, 17:11
Porco Wong (3 posts)
defmodule MyStr do

  def center(strList) do
    mlen = maxLen strList
    Enum.each strList, fn str ->
      l = String.length str
      str
        |> String.rjust(div((mlen - l), 2) + l)
        |> IO.puts
    end
  end

  defp maxLen(strList) do
    List.foldl strList, 0, fn (x, acc) ->
      xlen = String.length x
      cond do
        xlen > acc -> xlen
        true -> acc
      end
    end
  end

end
Generic-user-small
12 Nov 2014, 05:11
Elliot Finley (11 posts)

Here is my version. I try for code that is easy to reason about even if it is a little more verbose:

defmodule MyString do
  def center(list_of_strings) do
    max_length = list_of_strings
    |> Enum.max_by(&String.length/1)
    |> String.length

    list_of_strings
    |> Enum.each(&(print_centered(&1, max_length)))
  end

  defp print_centered(string, max_length) do
    padding = String.duplicate(" ", div(max_length-String.length(string),2))
    IO.write padding
    IO.puts string
  end
end
9863_pragsmall
05 Dec 2014, 21:15
Suraj Kurapati (15 posts)

I didn’t take the shortcut of padding only the left-hand side of each string because, although it works for the purpose of printing these strings to stdout, it would produce unwanted alignment if these strings were printed side-by-side on a single line.

defmodule MyString do
  def center(strings) do
    lengths = strings |> Enum.map(&String.length/1)
    max_len = lengths |> Enum.max
    for {str, len} <- Enum.zip(strings, lengths) do
      pad(str, max_len - len)
    end
  end

  defp pad(string, amount, using\\" ") do
    pad_left = String.duplicate(using, div(amount, 2))
    pad_right = String.duplicate(using, rem(amount, 2)) <> pad_left
    pad_left <> string <> pad_right
  end
end

For example:

iex(131)> MyString.center ~W[ cat zebra elephant ]
["  cat   ", " zebra  ", "elephant"]
5971263675_f01d667f5b_z_pragsmall
11 Dec 2014, 01:43
Stuart Blair (3 posts)

By comparison, mine is a little verbose. I suspect there’s actually a way to remove the duplication with the two justify functions by using a reference to the named functions rjust and ljust and just pass them as parameters to the function. Ah well, I’m sure I’ll get to that later in the book.

defmodule WordList do
  def center(words) do
    Enum.each(words, fn(word) -> formatWord(word, inTheContextOfThe(words)) end)
  end

  defp inTheContextOfThe(words) do
    fn(word) ->
      div(longestWordLength(words) - String.length(word), 2)
    end
  end

  defp longestWordLength(words) do
    Enum.max Enum.map(words, fn(word) -> String.length(word) end)
  end

  defp formatWord(word, paddingFor) do
    IO.puts leftJustifiedWord(rightJustifiedWord(word, paddingFor), paddingFor)
  end

  defp rightJustifiedWord(word, paddingFor) do
    String.rjust(word, String.length(word) + paddingFor.(word))
  end

  defp leftJustifiedWord(word, paddingFor) do
    String.ljust(word, String.length(word) + paddingFor.(word))
  end
end

Example:

WordList.center(["cat", "zebra", "José Ørstüd", "elephant"])
    cat
   zebra
José Ørstüd
 elephant
Generic-user-small
29 Dec 2014, 10:51
Pierre Sugar (56 posts)
defmodule MyString do
  def center(words) do
    max_length = (for x <- words, do: String.length(x))
                 |> Enum.max
    for x <- words, do: IO.puts center_word(x, max_length)
  end

  def center_word(word, length) do
    filler = String.duplicate(" ", div(length - String.length(word),2))
    filler <> word <> filler
  end
end
Generic-user-small
26 Jul 2015, 08:14
Dave (3 posts)
defmodule MyString do
  def print_centered(list) do
    max_len = Enum.map(list, &(String.length(&1))) |> Enum.max
    list
    |> Enum.sort_by(&(String.length(&1)))
    |> Enum.map(&(center(&1, max_len)))
    |> Enum.each(&(IO.puts(&1)))
  end

  def center(string, num) do
    string_len = String.length(string)
    just_len = div(num, 2) + div(string_len + rem(string_len, 2), 2)
    string
    |> String.ljust(just_len)
    |> String.rjust(2 * just_len - string_len)
  end
end
Generic-user-small
26 Jul 2015, 08:17
Dave (3 posts)

Also, how do you colour your function/module syntax?

4c5c2c297ed9f4664cfbe7733a011fb2_pragsmall
22 Aug 2015, 12:34
Artem Medeusheyev (8 posts)

Dave, start code block with “~~~elixir” to enable syntax highlighting.

defmodule Dqs do
  def center(strings) do
    longest = String.length Enum.max_by(strings, &String.length/1)
    Enum.map(strings, fn(str) ->
      len = String.length(str)
      just = div(longest - len, 2)
      str |> String.ljust(just + len) |> String.rjust(longest)
    end)
  end
end
  You must be logged in to comment