Эликсирная реализация ngram - PullRequest
       6

Эликсирная реализация ngram

0 голосов
/ 19 октября 2018

Я хочу разработать очень маленький скрипт, который читает предложение и генерирует в консоли вывод n-граммы.

Это пример

Example
"Show me the code."
Returns
[
  "Show",
  "Show me",
  "Show me the",
  "Show me the code",
  "me",
  "me the",
  "me the code",
  "the",
  "the code",
  "code"
]

Это мойкод:

defmodule M do
  def main do
    sentence = IO.gets("What is the sentence : ")
    ls = String.split(sentence)
    lsSize = length(ls)
    Enum.each 0..lsSize , fn(x) ->
      posNew = x+1
      IO.puts Enum.at(ls,x)
      Enum.each posNew..lsSize , fn(y) ->
        currentWord = Enum.join([Enum.at(ls,x),  Enum.at(ls,y)], " ")
        IO.puts(currentWord)
      end
    end
  end
end

Единственное, что я получаю, это:

What is the sentence : one two three
one
one two
one three
one
two
two three
two
three
three

Можете ли вы помочь мне с этим?Я не понимаю, почему значение currentCode не обновляется за пределами Enum.each и получает сброс.Я новичок в эрланге и эликсире, и поэтому я не понимаю проблемы в этом.

Спасибо!

1 Ответ

0 голосов
/ 19 октября 2018

Это потому, что вы соединяете только два слова одновременно. Ваш вызов Enum.join здесь объединяет только слова в позициях x и y, а не все слова между ними:

Enum.join([Enum.at(ls,x),  Enum.at(ls,y)], " ")

Вам необходимо объединить все слова в этом диапазоне:

Enum.join(Enum.slice(ls, x, y), " ")


Кроме того, в вашем коде все еще есть некоторые ошибки. Вот как вы можете разбить код на более мелкие методы для достижения того, что вы пытаетесь сделать:

defmodule NGram do
  def run do
    "Enter sentence: "
    |> IO.gets
    |> String.trim
    |> String.split(" ")
    |> build
    |> Enum.map(&IO.puts/1)
    :ok
  end

  def build(words) do
    words
    |> pre_walk
    |> Enum.map(&String.split(&1, " "))
    |> Enum.map(&post_walk/1)
    |> List.flatten
  end

  defp pre_walk(words) do
    length = length(words)

    Enum.map(0..(length-1), fn i ->
      words
      |> Enum.slice(i, length)
      |> Enum.join(" ")
    end)
  end

  defp post_walk(subwords) do
    Enum.map(1..length(subwords), fn i ->
      subwords
      |> Enum.slice(0, i)
      |> Enum.join(" ")
    end)
  end
end
...