2012-07-28 83 views
1

我想写类似下面的东西:二郎`现在,next`列表迭代

哈斯克尔:

Prelude> let xs = [1..10] 
Prelude> zip xs (tail xs) 
[(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,8),(8,9),(9,10)] 

二郎:

1> XS = [1,2,3,4,5,6,7,8,9,10]. 
[1,2,3,4,5,6,7,8,9,10] 
2> lists:zip(XS, tl(XS)). 
** exception error: no function clause matching lists:zip("\n",[]) (lists.erl, line 321) 
    in function lists:zip/2 (lists.erl, line 321) 
    in call from lists:zip/2 (lists.erl, line 321) 


now_nxt([X|Tail],XS) -> 
    [Y|_] = Tail, 
    now_nxt(Tail, [{X,Y}|XS]); 
now_nxt(_,XS) -> XS. 

156>coeffs:now_nxt(XS, []). 
** exception error: no match of right hand side value [] 

更新:

谢谢你的例子。我最后写了以下内容:

now_nxt_nth(Index, XS) -> 
    nnn(Index, XS, []). 


nnn(Index, XS, YS) -> 
    case Index > length(XS) of 
    true -> 
     lists:reverse(YS); 
    false -> 
     {Y,_} = lists:split(Index, XS), 
     nnn(Index, tl(XS), [Y|YS]) 
    end. 

回答

3

一(简单和有效的)从许多可能的解决方案:

now_nxt([H|T]) -> 
    now_nxt(H, T). 

now_nxt(_, []) -> []; 
now_nxt(A, [B|T]) -> [{A, B} | now_nxt(B, T)]. 
1

名单必须相等大小的使用lists:zip,TL(XS)时,显然会比XS一个短。

lists:zip(XS--[lists:last(XS)], tl(XS)). 

我认为通过从第一个输入列表中删除最后一个元素可以实现您要做的。

+0

所以,然后能够使用这个作为一般函数必须先测试'xs%2'? – beoliver 2012-07-28 19:29:09

+0

我不确定'xs%2'是什么意思,如果你的意思是列表的长度> = 2,那么你必须或者让它失败并捕获异常。 – 2012-07-28 20:07:03

0

另一种解决方案是:

lists:zip(lists:sublist(XS,length(XS)-1), tl(XS)). 

应当注意的是

L--[lists:last(L)] 

可以不删除最后一个元件。例如,

L = [1,2,3,4,1]. 
L -- [lists:last(L)] =/= [1,2,3,4]. % => true 
[2,3,4,1] = L -- [lists:last(L)].