Reference to generic type 'Dictionary' requires arguments in <..> [duplicate] - swift

let index1 = arc4random_uniform(10);
let x = array[index1];
The second line is giving following error
could not find an overload for 'subscript' that accepts the supplied arguments
let x = array[index1];
^~~~~~~~~~~~~

you have to convert the index to Int like e.g. this:
let index1: UInt32 = arc4random_uniform(10); // with the type of the value
let x = array[Int(index1)];
the Int is the proper index type rather than UInt32.
UPDATE
if you are not quiet happy to convert the index every individual time, you can also add an extension to Array with defining a new subscript for your generic index type(s), e.g. such extension would look with UInt32 like this:
extension Array {
subscript (index: UInt32) -> T {
get {
let intIndex : Int = Int(index)
return self[intIndex]
}
}
}
NOTE: I have not worked out the setter here.

Related

How to solve "Argument type 'CustomStruct' does not conform to expected type 'Sequence'"

I was trying to use the codes below to shuffle an array consisted of a simple custom struct called Card, and I get an error at cards.remove(at: randomIndex):
Error: Argument type 'Card' does not conform to expected type 'Sequence'
Here are the codes:
var cards = [Card]() // declare the array
var shuffledCards = [Card]()
for _ in cards.indices {
let randomIndex = Int(arc4random_uniform(UInt32(cards.count)))
shuffledCards += cards.remove(at: randomIndex) // error appears here
}
cards = shuffledCards
Oddly, as a contrast, the similar design works for Array<String>:
var emojiChoices = ["🦇", "😱", "🙀", "😈", "🎃", "👻", "🍭", "🍬", "🍎"]
let randomIndex = Int(arc4random_uniform(UInt32(emojiChoices.count)))
emoji[card.identifier] = emojiChoices.remove(at: randomIndex)
Should I add something the the definition of Card? If so, what should I add? Thanks!
The += operator in
shuffledCards += cards.remove(at: randomIndex)
expects a sequence of elements which should be append to the
shuffledCards array (for example another array). To append a single element, use
shuffledCards.append(cards.remove(at: randomIndex))

Subscript range of [UInt8] - Swift

So the issue I'm having is that I have an object with a argument in the init() that requires an [UInt8]. I want to be able to grab a range from another array and use that in the init. See example.
class Test {
init(fromArray: [UInt8]) {
// performs work
}
}
let myStockArray: [UInt8] = [1,2,3,4,5,6,7,8] // reference array
let test = Test(fromArray: myStockArray[1...4]) // doesn't work
How can I get this to work? The error I get is: Cannot subscript a value of type '[UInt8]' with an index of type 'CountableClosedRange'
Subscripting an array with a range doesn't return an array and this is the main issue. You are trying to setArraySlice<UInt8> type data to the constructor that have inside [UInt8] type.
Try this approach:
class Test {
init(fromArray: [UInt8]) {
// performs work
}
}
let myStockArray: [UInt8] = [1,2,3,4,5,6,7,8] // reference array
let test = Test(fromArray: Array(myStockArray[1...4]))

Creating an UnsafeMutablePointer<UnsafeMutablePointer<Float>> parameter in Swift 3

The Swift signature of the Accelerate framework vDSP_biquadm() function includes parameter types of UnsafeMutablePointer<UnsafePointer<Float>> and UnsafeMutablePointer<UnsafeMutablePointer<Float>>.
How does one declare and create such types in Swift 3, and then fill these pointer arrays with references to several Swift arrays of type [Float].
When you need to pass multiple values for UnsafeMutablePointer<T> parameters, you need to declare a variable of type [T] (aka Array<T>) and pass it as an inout argument. In your case T is UnsafeMutablePointer<Float>.
So, if you want to start with [Float], you may need to write something like this:
let input: [Float] = [/*...*/]
var output: [Float] = Array(repeating: 0, count: outputTotalSize)
input.withUnsafeBufferPointer {inBuf in
let inputPtr = inBuf.baseAddress!
output.withUnsafeMutableBufferPointer {outBuf in
let outputPtr = outBuf.baseAddress!
var pInputs: [UnsafePointer<Float>] = [inputPtr,/*...*/]
var pOutputs: [UnsafeMutablePointer<Float>] = [outputPtr/*...*/]
vDSP_biquadm(setup, &pInputs, inStride, &pOutputs, outStride, length)
}
}

Optional vs Bound value assigning var from array

I want to check if there is a value in a array and if so assign to a String using a if-left statement:
if let scoreValue = scoreValueArray[element!]{
// do something with scoreValue
}
Error: Bound value in a conditional binding must be of optional type
So tried changing the ! to ? but error persists.
Any input appreciated.
scoreValueArray is an array of strings, where a String value is appended to array if a condition is met, then array is saved to NSUserdefaults.
So element is a int which corresponds to a index in the array, bt only if the index is occupied with a String, so
scoreValueArray[element!]
could return an 'Index out of bounds', hence want to use the if-let.
Although the accepted answer clearly puts why optional binding is not available in the current implementation, it doesn't provide with a solution.
As it is shown in this answer, protocols provide an elegant way of safely checking the bounds of an array. Here's the Swift 2.0 version:
extension Array {
subscript (safe index: Int) -> Element? {
return indices ~= index ? self[index] : nil
}
}
Which you can use like this:
let fruits = ["Apple", "Banana", "Cherry"]
if let fruit = fruits[safe: 4] {
// Do something with the fruit
}
It's not clear what type your scoreValueArray is, but for the sake of this answer, I'm going to assume it's an array of Int.
var scoreValueArray: Array<Int>
Now, if we look the definition of the Array struct, we'll find this:
struct Array<T> : MutableCollectionType, Sliceable {
// other stuff...
subscript (index: Int) -> T
// more stuff
}
So, calling the subscript method on our array (which is what we do when we say scoreValueArray) returns a non-optional. And non-optionals cannot be used in the conditional binding if let/if var statements.
We can duplicate this error message in a more simple example:
let foo: Int = 3
if let bar = foo {
// same error
}
This produces the same error. If we instead do something more like the following, we can avoid the error:
let foo: Int? = 3
if let bar = foo {
// perfectly valid
}
This is different from a dictionary, whose subscript method does return an optional (T?). A dictionary will return a value if the key passed in the subscript is found or nil if there is no value for the passed key.
We must avoid array-index-out-of-bounds exceptions in the same way we always do... by checking the array's length:
if element < scoreValueArray.count {
scoreValue = scoreValueArray[element]
}

Swift access array with index gives following error. Any idea why?

let index1 = arc4random_uniform(10);
let x = array[index1];
The second line is giving following error
could not find an overload for 'subscript' that accepts the supplied arguments
let x = array[index1];
^~~~~~~~~~~~~
you have to convert the index to Int like e.g. this:
let index1: UInt32 = arc4random_uniform(10); // with the type of the value
let x = array[Int(index1)];
the Int is the proper index type rather than UInt32.
UPDATE
if you are not quiet happy to convert the index every individual time, you can also add an extension to Array with defining a new subscript for your generic index type(s), e.g. such extension would look with UInt32 like this:
extension Array {
subscript (index: UInt32) -> T {
get {
let intIndex : Int = Int(index)
return self[intIndex]
}
}
}
NOTE: I have not worked out the setter here.