swift - How to enumerate a slice using the original indices? -
if want enumerate array (say map()
function need use index of element value), use enumerate()
function. e.g.:
import foundation let array: [double] = [1, 2, 3, 4] let powersarray = array.enumerate().map() { pow($0.element, double($0.index)) } print("array == \(array)") print("powersarray == \(powersarray)") // array == [1.0, 2.0, 3.0, 4.0] // powersarray == [1.0, 2.0, 9.0, 64.0] <- expected
now, if want use sub-sequence array, use slice
, , allow me use same indices use in original array (which want in case if use subscript
accessor in for
loop). e.g.:
let range = 1..<(array.count - 1) let slice = array[range] var powersslice = [double]() index in slice.indices { powersslice.append(pow(slice[index], double(index))) } print("powersslice == \(powersslice)") // powersslice == [2.0, 9.0] <- expected
however, should try use enumerate().map()
approach did original array, totally different behaviour. instead of slice
's range of indices new, 0-based range:
let powerssliceenumerate = slice.enumerate().map() { pow($0.element, double($0.index)) } print("powerssliceenumerate == \(powerssliceenumerate)") // powerssliceenumerate == [1.0, 3.0] <- not expected
question whether there decent way (i.e. without manual adjustments using offsets, or something) enumerate slice using own indices , not auto-generated 0-based ones?
enumerate()
returns sequence of (n, elem)
pairs, n
s consecutive int
s starting @ zero. makes sense because protocol extension method sequencetype
, , arbitrary sequence not have index associated elements.
you expected result with
let powersslice = slice.indices.map { pow(slice[$0], double($0)) }
or
let powersslice = zip(slice.indices, slice).map { pow($1, double($0)) }
the latter approach generalized protocol extension method arbitrary collections:
extension collectiontype { func indexenumerate() -> anysequence<(index: index, element: generator.element)> { return anysequence(zip(indices, self)) } }
this returns sequence of (index, elem)
pairs index
index of collection , elem
corresponding element. anysequence
used "hide" specific type zip2sequence<rangegenerator<self.index>, self>
returned zip()
caller.
example:
let powerssliceenumerate = slice.indexenumerate().map() { pow($0.element, double($0.index)) } print("powerssliceenumerate == \(powerssliceenumerate)") // powerssliceenumerate == [2.0, 9.0]
update swift 3:
extension collection { func indexenumerate() -> anysequence<(indices.iterator.element, iterator.element)> { return anysequence(zip(indices, self)) } }
Comments
Post a Comment