on master help sign in
Make meaning of Array.slice match String.slice

This is the meaning used by JS, Python, Clojure, and Scala at least. I hope Dijkstra would be pleased.

commit513ce27cc666616cd133b50b43b37103fbde1cec authorEvan Czaplicki <info@elm-lang.org> dateWed 30 Apr 2014, 18:01 (13 years ago) parent7a6a0fa
3 files changed+20−14
libraries/Array.elm+15−7 libraries/Native/Array.js+1−4 tests/elm/Test/Array.elm+4−3
libraries/Array.elm+15−7
@@ -14,7 +14,7 @@ reads, updates, and appends.
1414@docs get, getOrElse, getOrFail, set
1515
1616# Taking Arrays Apart
17−@docs toList, toIndexedList, slice
17+@docs slice, toList, toIndexedList
1818
1919# Mapping and Folding
2020@docs map, indexedMap, foldl, foldr
@@ -163,13 +163,21 @@ If the index is out of range, the array is unaltered.
163163set : Int -> a -> Array a -> Array a
164164set = Native.Array.set
165165
166−{-| Slice an array given a range. The selection is inclusive, so the last
167−element in the selection will also be in the new array. This may change in the
168−future. You can select from the end by giving a negative Int.
166+{-| Get a sub-section of an array: `(slice start end array)`. The `start` is a
167+zero-based index where we will start our slice. The `end` is a zero-based index
168+that indicates the end of the slice. The slice extracts up to but not including
169+`end`.
169170
170− slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
171− slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
172− slice -3 -2 (fromList [0,1,2,3,4]) == fromList [2,3]
171+ slice 0 3 (fromList [0,1,2,3,4]) == fromList [0,1,2]
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]
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`
173181-}
174182slice : Int -> Int -> Array a -> Array a
175183slice = Native.Array.slice
libraries/Native/Array.js+1−4
@@ -262,9 +262,6 @@ Elm.Native.Array.make = function(elm) {
262262 return b;
263263 }
264264
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.
268265 // TODO: currently, it slices the right, then the left. This can be
269266 // optimized.
270267 function slice(from, to, a) {
@@ -281,7 +278,7 @@ Elm.Native.Array.make = function(elm) {
281278 // Handle leaf level.
282279 if (a.height == 0) {
283280 var newA = { ctor:"_Array", height:0 };
284− newA.table = a.table.slice(0, to + 1);
281+ newA.table = a.table.slice(0, to);
285282 return newA;
286283 }
287284
tests/elm/Test/Array.elm+4−3
@@ -39,9 +39,10 @@ tests =
3939 takingArraysApartTests = suite "Taking Arrays Apart"
4040 [ test "toList" <| assertEqual [3,5,8] (Array.toList (Array.fromList [3,5,8]))
4141 , 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]))
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 [2,3]) (Array.slice -3 -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]))
44+ , test "slice 3" <| assertEqual (Array.fromList [1,2,3]) (Array.slice 1 -1 (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]))
4546 ]
4647 mappingAndFoldingTests = suite "Mapping and Folding"
4748 [ test "map" <| assertEqual (Array.fromList [1,2,3]) (Array.map sqrt (Array.fromList [1,4,9]))