【问题标题】:How to sort a list based on the original list? [duplicate]如何根据原始列表对列表进行排序? [复制]
【发布时间】:2016-12-03 00:17:27
【问题描述】:

如何根据另一个列表对列表进行排序,例如:

列表 = [1,2,3,4,5]。

我有一个发送这个列表的函数和一个将列表元素应用到工作人员的函数,例如:

发件人(列表,F)

worker() 将应用 F(列表的元素)

并将元素一一发回发送者函数。 这里,发送元素的结果可能与发送者发送的顺序不同。 所以,如果我发送 [1,2,3,4,5],工作人员可能会以这种方式发回列表

[结果(2),结果(5),结果(1),结果(4),结果(3)]

我的问题是:如何根据原始列表对结果列表进行排序

【问题讨论】:

标签: erlang


【解决方案1】:

tldr;这里的简短回答是,如果您想保留排序,工作人员需要知道他们正在处理的元素的索引并将其返回给调用者,以便重新组合列表

我建议将项目的索引发送给每个工人(例如F(Element, Index))。然后,不仅仅是将结果发回,而是发送结果和索引 ({Index, Result}),这样当您从每个工作人员那里获得结果时,您就知道它在列表中的位置。然后使用选择性接收将它们按顺序放回:

results_from_workers(Max) ->
  results_from_workers(Max, 0, []).

results_from_workers(Max, Num, NewList) when Num > Max ->
  % If the next number is greater than the max, reverse the list and return it
  lists:reverse(NewList);
results_from_workers(Max, Num, NewList) ->
  % Receive the result for the next number
  receive
    {Num, Result} ->
      results_from_workers(Num + 1, [Result|NewList])
  end.

% Then call your code that starts the workers
sender(List,F),

% Then call `results_from_workers/1` with the length of the list being processed, it should return the new list
NewList = results_from_workers(length(List)).

这样做的缺点是,如果进程崩溃,results_from_workers 进程将挂起,等待崩溃进程的结果。您应该将您的工作进程链接到启动它们的进程,所以这应该不是问题。如果由于某种原因您不能或不想链接到工作进程,您可以在接收中使用after Timeout -> failed 子句,Timeout 是一个整数,以毫秒为单位表示超时。请注意,如果您的工作人员花费的时间比预期的要长,则可能会执行超时子句,而您没有结果。

【讨论】:

  • 向原始列表添加更多信息(即元素的索引)的基本思想在这里很重要。答案的其余部分是推测性的,包括很多没有被要求的信息。
  • aronisstav,谢谢在我的回答中添加了一个 tldr。
  • 谢谢,erlang中是否有定义函数来检查列表元素的索引?
  • lists:nth/2 返回指定索引处的元素。除此之外,您还需要编写自己的函数或列表推导。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 2013-09-17
  • 2020-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多