#list #function #pagination #elixir
#Список #функция #разбивка на страницы #elixir
Вопрос:
Я новичок в Elixir, но мои поиски в Google и чтение не нашли мне решения моей текущей проблемы. Я видел только примеры в книгах и руководствах с передачей одного параметра списка в функцию следующим образом: [ 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)
Любые идеи о том, что я могу делать неправильно? (Прошу прощения, если это простой вопрос для ответа. Я не смог найти никакого ответа после нескольких часов поиска и игры с этим.)
Ответ №1:
Ваши проблемы связаны с совпадением шаблона аргумента списка. Для list
аргументов paginated
и вам не нужно заключать их в список, так как на самом деле вы будете сопоставлять их во вложенном списке. Кроме того, в Elixir принято использовать регистр snake для имен функций. Попробуйте сделать это:
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
Ответ №2:
@Chris решил проблему с сообщением об ошибке, с которым вы столкнулись, я только добавлю, что сигнатуры методов не очень «эликсирны».
Следующие подписи методов больше соответствуют духу и стилю кодирования языка (я изменил некоторые имена параметров, чтобы они были более удобочитаемыми):
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