如何在结构中模式匹配嵌套列表?

时间:2016-06-01 18:23:07

标签: elixir

如果给出以下示例,是否可以匹配条目是一个列表还是TodoEntry列表?

defmodule Todo do
    defstruct [:entries]

    def add_entry(%Todo{entries: _} = todo, %TodoEntry{date: {_, _, _}, title: _} = entry) do

    end 
end

defmodule TodoEntry do
    defstruct [:date, :title]
end

2 个答案:

答案 0 :(得分:1)

以下代码应该适合您:

defmodule TodoEntry do
    defstruct [:date, :title]
end

defmodule Todo do
  defstruct [:entries]

  def add_entry(%Todo{entries: nil} = todo, %TodoEntry{} = entry) do
    %Todo{entries: [entry]}
  end

  def add_entry(%Todo{entries: [%TodoEntry{}|_]} = todo, %TodoEntry{} = entry) do
    %Todo{entries: [entry | todo.entries]}
  end  
end

我假设您希望它的功能如下:

todo = %Todo{}

entry = %TodoEntry{date: {2,6,2016}, title: "My new Todo"}
todo = Todo.add_entry(todo,entry)

entry = %TodoEntry{date: {2,6,2017}, title: "My todo next year"}
todo = Todo.add_entry(todo,entry)

entry = %TodoEntry{date: {2,6,2026}, title: "My new todo next decade, if I cared"}
todo = Todo.add_entry(todo,entry)

答案 1 :(得分:0)

这是我最终的结果。虽然我觉得我正在投入大量精力来验证传入的预期结构。

defmodule TodoEntry do
    defstruct [:date, :title]

    def create(entry) do
        %TodoEntry{date: {_, _, _}, title: _} = entry
    end
end

defmodule Todo do
    defstruct [:entries]

    def new do
        %Todo{entries: []}
    end 

    def add_entry(%Todo{entries: []} = todo, entry) do      
        entry = TodoEntry.create(entry)
        entries = update_entries(entry, todo.entries) 

        %Todo{todo | entries: entries}
    end 

    def add_entry(%Todo{entries: [_]} = todo, entry) do 
        entries = [%TodoEntry{date: {_, _, _}, title: _}] =  todo.entries
        entry   = TodoEntry.create(entry)

        entries = update_entries(entry, entries) 

        %Todo{todo | entries: entries}
    end 

    defp update_entries(entry, entries) do
        [entry | entries]
    end