PageRenderTime 18ms CodeModel.GetById 12ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/mod_base/filters/filter_slice.erl

https://code.google.com/p/zotonic/
Erlang | 93 lines | 39 code | 14 blank | 40 comment | 0 complexity | 025ca8a63ffda790205158b451a2c629 MD5 | raw file
 1%% @author Dmitrii Dimandt <dmitrii@dmitriid.com>
 2%% @copyright 2011 Dmitrii Dimandt
 3%% @doc 'slice' filter, get a range of elements from a list
 4
 5%% Copyright 2011 Dmitrii Dimandt
 6%%
 7%% Licensed under the Apache License, Version 2.0 (the "License");
 8%% you may not use this file except in compliance with the License.
 9%% You may obtain a copy of the License at
10%% 
11%%     http://www.apache.org/licenses/LICENSE-2.0
12%% 
13%% Unless required by applicable law or agreed to in writing, software
14%% distributed under the License is distributed on an "AS IS" BASIS,
15%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16%% See the License for the specific language governing permissions and
17%% limitations under the License.
18
19% 
20% Given a list = [1,2,3,4,5,6,7,8,9,0]
21%
22% Get all elements from element M to element N:
23% {{ list|slice:[3,7] }} -> [3,4,5,6,7]
24% {{ list|slice:[3,-3] }} -> [3,4,5,6,7]
25% {{ list|slice:[-7,-3] }} -> [3,4,5,6,7]
26% {{ list|slice:[-7,7] }} -> [3,4,5,6,7]
27%
28% Get all elements except the first N:
29% {{ list|slice:[3,] }} -> [3,4,5,6,7,8,9,0]
30% {{ list|slice:[-7,] }} -> [3,4,5,6,7,8,9,0]
31%
32% Get all elements up to element N
33% {{ list|slice:[,3] }} -> [1,2,3]
34% {{ list|slice:[3] }} -> [1,2,3]
35%
36% Get all elements except the last N:
37% {{ list|slice:[,-3] }} -> [1,2,3,4,5,6,7]
38% {{ list|slice:[-3] }} -> [1,2,3,4,5,6,7]
39%
40% {{ list|slice:[M,N] }}, where N < M will return []
41% {{ list|slice:[,] }}, where N < M will return [1,2,3,4,5,6,7,8,9,0]
42%
43
44-module(filter_slice).
45-export([slice/3]).
46
47
48slice(undefined, _, _Context) ->
49    undefined;
50
51slice(List, Slice, _Context) when is_list(List) ->
52    slice1(List, Slice);
53slice(MaybeList, Slice, Context) ->
54    slice1(erlydtl_runtime:to_list(MaybeList, Context), Slice).
55
56slice1(List, [undefined, undefined]) ->
57    slice2(List, 1, length(List));
58
59slice1(List, [M, undefined]) ->
60    slice2(List, M, length(List));
61
62slice1(List, [undefined, N]) ->
63    N1 = if
64            N < 0 -> length(List) + N;
65            true -> N
66    end,
67    slice2(List, 1, N1);
68
69slice1(List, [M, N]) ->
70    slice2(List, M, N);
71
72slice1(List, [M]) ->
73    slice1(List, [undefined, M]);
74
75slice1(List, M) ->
76    slice1(List, [undefined, z_convert:to_integer(M)]).
77
78
79slice2(List, M, N) ->
80    M1 = if
81            M =:= 0 -> throw({error, invalid_index});
82            M < 0 -> length(List) + M;
83            true -> M
84    end,
85    N1 = if
86            N =:= 0 -> throw({error, invalid_index});
87            N < 0 -> length(List) + N;
88            true -> N
89    end,
90    if
91        N1 < M1 -> [];
92        true  -> lists:sublist(List, M1, N1 - M1 + 1)
93    end.