如何基于另一个列表对列表进行排序,例如:
列表= [1,2,3,4,5]。
我有一个函数发送此列表和一个函数,以便将列表元素应用于worker,例如:
发件人(List,F)
worker()将应用F(列表元素)
并将发送方函数逐个发送回元素。 这里,发送元素的结果可能与发送者发送的顺序不同。 所以,如果我发送[1,2,3,4,5],工人可能会以这种方式发回列表
[结果(2),结果(5),结果(1),结果(4),结果(3)]
我的问题是:如何根据原始列表对结果列表进行排序
答案 0 :(得分: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
是表示超时的整数(以毫秒为单位)。请注意,如果您的工作时间超过预期,则可能会执行timeout子句,但不会产生结果。