on master help sign in
Make meaning of Array.slice match String.slice
513ce27Evan Czaplicki
libraries/Array.elm+15−7
@@ -14,7 +14,7 @@ reads, updates, and appends.
14@docs get, getOrElse, getOrFail, set
14@docs get, getOrElse, getOrFail, set
15
15
16# Taking Arrays Apart
16# Taking Arrays Apart
17−@docs toList, toIndexedList, slice
17+@docs slice, toList, toIndexedList
18
18
19# Mapping and Folding
19# Mapping and Folding
20@docs map, indexedMap, foldl, foldr
20@docs map, indexedMap, foldl, foldr
@@ -163,13 +163,21 @@ If the index is out of range, the array is unaltered.
163set : Int -> a -> Array a -> Array a
163set : Int -> a -> Array a -> Array a
164set = Native.Array.set
164set = Native.Array.set
165
165
166−{-| Slice an array given a range. The selection is inclusive, so the last
166+{-| Get a sub-section of an array: `(slice start end array)`. The `start` is a
167−element in the selection will also be in the new array. This may change in the
167+zero-based index where we will start our slice. The `end` is a zero-based index
168−future. You can select from the end by giving a negative Int.
168+that indicates the end of the slice. The slice extracts up to but not including
169+`end`.
169
170
170− slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
171+ slice 0 3 (fromList [0,1,2,3,4]) == fromList [0,1,2]
171− slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
172+ slice 1 4 (fromList [0,1,2,3,4]) == fromList [1,2,3]
173+
174+Both the `start` and `end` indexes can be negative, indicating an offset from
175+the end of the array.
176+
177+ slice 1 -1 (fromList [0,1,2,3,4]) == fromList [1,2,3]
172− slice -3 -2 (fromList [0,1,2,3,4]) == fromList [2,3]
178+ slice -2 5 (fromList [0,1,2,3,4]) == fromList [3,4]
179+
180+This makes it pretty easy to `pop` the last element off of an array: `slice 0 -1 array`
173-}
181-}
174slice : Int -> Int -> Array a -> Array a
182slice : Int -> Int -> Array a -> Array a
175slice = Native.Array.slice
183slice = Native.Array.slice
libraries/Native/Array.js+1−4
@@ -262,9 +262,6 @@ Elm.Native.Array.make = function(elm) {
262 return b;
262 return b;
263 }
263 }
264
264
265− // Returns a sliced tree. "to" is inclusive, but this may change,
266− // when I understand, why e.g. JS does not handle it this way. :-)
267− // If "from" or "to" is negative, they will select from the end on.
268 // TODO: currently, it slices the right, then the left. This can be
265 // TODO: currently, it slices the right, then the left. This can be
269 // optimized.
266 // optimized.
270 function slice(from, to, a) {
267 function slice(from, to, a) {
@@ -281,7 +278,7 @@ Elm.Native.Array.make = function(elm) {
281 // Handle leaf level.
278 // Handle leaf level.
282 if (a.height == 0) {
279 if (a.height == 0) {
283 var newA = { ctor:"_Array", height:0 };
280 var newA = { ctor:"_Array", height:0 };
284− newA.table = a.table.slice(0, to + 1);
281+ newA.table = a.table.slice(0, to);
285 return newA;
282 return newA;
286 }
283 }
287
284
tests/elm/Test/Array.elm+4−3
@@ -39,9 +39,10 @@ tests =
39 takingArraysApartTests = suite "Taking Arrays Apart"
39 takingArraysApartTests = suite "Taking Arrays Apart"
40 [ test "toList" <| assertEqual [3,5,8] (Array.toList (Array.fromList [3,5,8]))
40 [ test "toList" <| assertEqual [3,5,8] (Array.toList (Array.fromList [3,5,8]))
41 , test "toIndexedList" <| assertEqual [(0,"cat"), (1,"dog")] (Array.toIndexedList (Array.fromList ["cat","dog"]))
41 , test "toIndexedList" <| assertEqual [(0,"cat"), (1,"dog")] (Array.toIndexedList (Array.fromList ["cat","dog"]))
42− , test "slice 1" <| assertEqual (Array.fromList [1,2]) (Array.slice 1 2 (Array.fromList [0,1,2,3,4]))
42+ , test "slice 1" <| assertEqual (Array.fromList [0,1,2]) (Array.slice 0 3 (Array.fromList [0,1,2,3,4]))
43+ , test "slice 2" <| assertEqual (Array.fromList [1,2,3]) (Array.slice 1 4 (Array.fromList [0,1,2,3,4]))
43− , test "slice 2" <| assertEqual (Array.fromList [1,2,3]) (Array.slice 1 -2 (Array.fromList [0,1,2,3,4]))
44+ , test "slice 3" <| assertEqual (Array.fromList [1,2,3]) (Array.slice 1 -1 (Array.fromList [0,1,2,3,4]))
44− , test "slice 3" <| assertEqual (Array.fromList [2,3]) (Array.slice -3 -2 (Array.fromList [0,1,2,3,4]))
45+ , test "slice 4" <| assertEqual (Array.fromList [2]) (Array.slice -3 -2 (Array.fromList [0,1,2,3,4]))
45 ]
46 ]
46 mappingAndFoldingTests = suite "Mapping and Folding"
47 mappingAndFoldingTests = suite "Mapping and Folding"
47 [ test "map" <| assertEqual (Array.fromList [1,2,3]) (Array.map sqrt (Array.fromList [1,4,9]))
48 [ test "map" <| assertEqual (Array.fromList [1,2,3]) (Array.map sqrt (Array.fromList [1,4,9]))