Elixir-处理二维列表

时间:2019-01-01 16:51:34

标签: arraylist types elixir

即使我们只是一天,希望每个人都拥有一个美好的2019年。

我目前正在开发一个小型Phoenix应用程序,在其中处理PDF文件(在这个问题的背景下,我将它们拆分),然后将其上传到S3。稍后,我必须删除pdftk(一种pdf工具)创建的临时文件,我将它们用于拆分,并在响应正文中显示s3链接,因为这是一个API请求。

我的组织方式如下:

在我的Split模块中,核心业务逻辑是:

filenames = []
 s3_links = []
 Enum.map(pages, fn(item) ->
        split_filename = item
          |> split(filename)
        link = split_filename
          |> FileHelper.result_file_bytes()
          |> ManageS3.upload()
          |> FileHelper.save_file(work_group_id, pass)

        [filenames ++ split_filename, s3_links ++ link]
      end)
      |> transform()
    {filenames, s3_links}

重要的是split_filename和链接 这是我在transform()方法中调用IO.inspect时得到的:

[
  ["87cdcd73-5b27-4757-a472-78aaf6cc6864.pdf",
   "Some_S3_LINK00"],

  ["0ab460ca-5019-4864-b0ff-343966c7d72a.pdf",
   "Some_S3_LINK01"]
]

结构为[[filename, s3_link], [filename, s3_link]],而所需结果将为[ [list of all filenames], [list of s3 links]

如果有人可以伸出援手,我将非常感激。预先感谢!

2 个答案:

答案 0 :(得分:1)

您可能要考虑将元组与列表一起使用,而不是处理列表列表。像下面这样的东西应该适合您。

List.foldl(pages, {[], []}, fn(item, {filenames, links}) ->
  filename = split(item, filename)

  link =
    file_name
    |> FileHelper.result_file_bytes()
    |> ManagerS3.upload()
    |> FileHelper.save_file(work_group_id, pass)

  {[filename | filenames], [link | links]}
end)

这将返回一个看起来像

的值
{
  ["87cdcd73-5b27-4757-a472-78aaf6cc6864.pdf",
   "0ab460ca-5019-4864-b0ff-343966c7d72a.pdf"],

  ["Some_S3_LINK00",
   "Some_S3_LINK01"]
}

但是,根据您使用这些值的方式,也许元组列表会更合适。像

Enum.map(pages, fn(item) ->
  filename = split(item, filename)

  link =
    filename
    |> FileHelper.result_file_bytes()
    |> ManageS3.upload()
    |> FileHelper.save_file(work_group_id, pass)

  {filename, link}
end)

会返回

[
  {"87cdcd73-5b27-4757-a472-78aaf6cc6864.pdf", "Some_S3_LINK00"},
  {"0ab460ca-5019-4864-b0ff-343966c7d72a.pdf", "Some_S3_LINK01"}
]

答案 1 :(得分:1)

侧注:

  1. 最开始分配filenames = []; s3_links = []的意义为零。 Enum.map映射输入。您可能需要的是Enum.reduce/3
  2. 当管道由唯一的调用组成时,请勿使用管道|>运算符,Elixir核心团队将其视为反模式。
  3. 总是以术语开始管道。

解决方案:

直接使用Enum.reduce/3将输入减少到结果中即可。

pages
|> Enum.reduce([[], []], fn item, [files, links] ->
  split_filename = split(item, filename)
  link =
    split_filename
    |> FileHelper.result_file_bytes()
    |> ManageS3.upload()
    |> FileHelper.save_file(work_group_id, pass)

  [[split_filename | files], [link | links]]
end)
|> Enum.map(&Enum.reverse/1)
|> IO.inspect(label: "Before transform")
|> transform()

您没有提供用于测试的输入,但是我认为它应该可以工作。