> Hi All,
> after a long time, here I am programming in Erlang again...
> I have 2 lists:
> L1=[1,2,3,4,5], L2=[1.1,2.2,3.3,4.4,5.5]
> and I want to have a third list which is the difference of them:
> L3=[
> L2[1] - L1[1],
> L2[2] - L1[2],
> L2[3] - L1[3],
> L2[4] - L1[4],
> L2[5] - L1[5]
> ]
> The result should be
> L3=[0.1,0.2,0.3,0.4,0.5]
>
> I have tried:
>
> sub(L2,L1) -> [X2-X1||X1<-L1,X2<-L2].
This says
for each X1 in L1 {
for each X2 in L2 {
include X1 - X2 in the result
}
}
just like it does in Haskell and Clean.
Direct method:
sub([X|Xs], [Y|Ys]) -> [X-Y | sub(Xs, Ys)];
sub([], []) -> [].
Zip then enumerate pairs:
sub(Xs, Ys) -> [X-Y || {X,Y} <- lists:zip(Xs, Ys)].
Zip with a function other than pairing:
sub(Xs, Ys) -> lists:zipwith(fun (X, Y) -> X - Y end, Xs, Ys).
One expects a Haskell compiler to expand calls to zip.
One expects an Erlang compiler NOT to, and it doesn't.
There's an EEP proposing that you should be allowed to write
** sub(Xs, Ys) -> [X-Y || X <- Xs && Y <- Ys]
but that's not allowed in Erlang yet.
以上内容来自 erlang_quest mail
我看到上面提用 直接方法和lists:zip/2 及lists:zipwith/3 三种方法解决此问题。
带着疑问看来了一下源码,原来这三种方法是的思路是一样的。
list:zip/2的源码 如下
zip([X | Xs], [Y | Ys]) -> [{X, Y} | zip(Xs, Ys)];
zip([], []) -> [].
zipwith 的如下:
zipwith(F, [X | Xs], [Y | Ys]) -> [F(X, Y) | zipwith(F, Xs, Ys)];
zipwith(F, [], []) when is_function(F, 2) -> [].