I'm looking to extract sub-arrays in Swift 4 and running into unexpected difficulties.
The following trivial cases work as expected:
let array1 = ["a", "b", "c","x","y","z"]
array1[2...3] // returns ["c","x"], as it should
as does the following variation:
let m=2
let n=3
array1[m...n] // returns ["c","x"], as it should
But if I try to create a function around this, I get an error message ambiguous subscript with base type 'Array<Any>' and index type 'CountableClosedRange<Int>'
:
func arrayTake(arrayIn: Array<Any>) -> Array<Any> {
return arrayIn[2...3]
} // no good
And of course, the following form, which is closer to what I actually want to do, fails with the same error message:
func arrayTake(m: Int, n: Int, arrayIn: Array<Any>) -> Array<Any> {
return arrayIn[m...n]
} // no good
I have seen other questions here about ambiguous subscripts but have not been able to translate the answers there into a solution to my problem. Any guidance would be appreciated.
You are getting such error because you are trying to return an ArraySlice instead of the expected Array<Any>
:
Slices Are Views onto Arrays
You may want to convert such slice using a dedicated Array constructor:
func arrayTake(m: Int, n: Int, arrayIn: Array<Any>) -> Array<Any> {
return Array<Any>(arrayIn[m...n])
}
Moreover, please note that long-term storage of ArraySlice
is discouraged, a slice holds a reference to the entire storage of a larger array, not just to the portion it presents, even after the original array’s lifetime ends. Long-term storage of a slice may therefore prolong the lifetime of elements that are no longer otherwise accessible, which can appear to be memory and object leakage.
Problem is Datatype mismatch.
array1[2...3]
This statement does not return Array it returns ArraySlice a special DataType (struct) for this kind of array operation.
So you can solve this by two way.
Change return type to ArraySlice
func arrayTake(m: Int, n: Int, arrayIn: Array<Any>) -> ArraySlice<Any>
{
return arrayIn[m...n]
}
OR
Convert ArraySlice to Array
func arrayTake(m: Int, n: Int, arrayIn: Array<Any>) -> Array<Any> {
return Array(arrayIn[m...n])
}
Both will print same output but keep in mind that they are not same:
let array1 = ["a", "b", "c","x","y","z"]
let result = arrayTake(m: 2, n: 3, arrayIn: array1)
print(result) //["c","x"], as it should
Check this for more detail: https://medium.com/@marcosantadev/arrayslice-in-swift-4e18522ab4e4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With