代码之家  ›  专栏  ›  技术社区  ›  beoliver

Erlang“现在下一个”列表迭代

  •  1
  • beoliver  · 技术社区  · 13 年前

    我正试图写一些类似于以下内容的东西:

    哈斯克尔:

    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 回复  |  直到 13 年前
        1
  •  3
  •   Hynek -Pichi- Vychodil Paulo Suassuna    13 年前

    多种可能方案中的一种(简单高效)解决方案:

    now_nxt([H|T]) ->
      now_nxt(H, T).
    
    now_nxt(_, []) -> [];
    now_nxt(A, [B|T]) -> [{A, B} | now_nxt(B, T)].
    
        2
  •  1
  •   Scott Logan    13 年前

    使用时,列表的大小必须相等 lists:zip ,tl(XS)将明显比XS短一个。

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

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

        3
  •  0
  •   Jared    13 年前

    另一种解决方案是:

    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)].