Elixir - 将多个列表作为函数参数传递

时间:2014-06-27 11:18:07

标签: list function pagination elixir

我是Elixir的新手但我的谷歌搜索和阅读并没有找到解决我当前问题的方法。我只看到书籍和教程中的示例,将单个列表参数传递给如下函数:[ head | tail ]

defmodule Math do
  def double_each([head|tail]) do
    [head * 2| double_each(tail)]
  end

  def double_each([]) do
    []
  end
end

我需要传入两个列表,然后对它们执行一些操作,如下所示:

defmodule Pagination do
  def getPaginatedList([], _, _, _) do
    []
  end

  def getPaginatedList([list], [paginated], f, l) when f == 1 do
    Enum.take(list, l)
  end

  def getPaginatedList(_, [paginated], f, l) when l <= f do
    paginated
  end

  def getPaginatedList([list], [paginated] \\ [], f, l) do
    getPaginatedList(tl(list), paginated ++ hd(list), f, l - 1)
  end
end

但是,在传递a的列表和b的列表时,我收到有关函数子句不匹配的错误,如下面的错误所示:

iex(23)> Pagination.getPaginatedList(a, b, 1, 2)
** (FunctionClauseError) no function clause matching
      in Pagination.getPaginatedList/4
    pagination.ex:2: Pagination.getPaginatedList([1, 2, 3, 4, 5], [], 1, 2)

关于我可能做错的任何想法? (道歉,如果这是一个简单的问题要回答。经过几个小时的搜索和玩弄后,我找不到任何答案。)

2 个答案:

答案 0 :(得分:4)

您的问题是列表参数模式匹配。对于listpaginated参数,您不需要将它们包装在列表中,因为您实际上是在嵌套列表上进行匹配。此外,在Elixir中使用蛇形盒作为功能名称是常规的。试试这个:

defmodule Pagination do
  def get_paginated_list([], _, _, _) do
    []
  end

  def get_paginated_list(list, paginated, f, l) when f == 1 do
    Enum.take(list, l)
  end

  def get_paginated_list(_, paginated, f, l) when l <= f do
    paginated
  end

  def get_paginated_list(list, paginated \\ [], f, l) do
    get_paginated_list(tl(list), paginated ++ hd(list), f, l - 1)
  end
end

答案 1 :(得分:0)

@Chris解决了您遇到的错误消息,我只会补充说方法签名不是很好&#34; elixirish&#34;。

以下方法签名更符合语言的精神和编码风格(我已将某些参数名称更改为更易读):

defmodule Pagination do
  def get_paginated_list([], _, _, _) do
    []
  end

  def get_paginated_list(list, _, page_num, page_size) when page_num == 1 do
    Enum.take(list, page_size)
  end

  def get_paginated_list(_, paginated, page_num, page_size) when page_size <= page_num do
    paginated
  end

  def get_paginated_list([head | tail], paginated \\ [], page_num, page_size) do
    get_paginated_list(tail, paginated ++ [head], page_num, page_size - 1)
  end
end

我不完全确定您的代码的语义应该是什么,但对于分页,我想您可能希望查看Enum.chunk/4,您可能会这样使用:

defmodule Pagination do   
  def get_paginated_list(list, page_num, page_size) do
    list |> Enum.chunk(page_size, page_size, []) |>  Enum.at(page_num)
  end
end

Pagination.get_paginated_list([1, 2, 3, 4, 5], 1, 3)
# => [4, 5]
Pagination.get_paginated_list([1, 2, 3, 4, 5], 0, 3)
# => [1, 2, 3]
Pagination.get_paginated_list([1, 2, 3, 4, 5], 2, 3)
# => nil