Error cannot invoke initializer for type 'Range<_>' with an argument list of type '(Range<String.Index>)' - swift

Why do I get the error, Cannot invoke initializer for type 'Range<_>' with an argument list of type '(Range)'
extension String {
subscript (i: Int) -> Character {
if self.isEmpty {
return Character("")
}
if i > self.characters.count {
return Character("")
}
return self[self.index(self.startIndex, offsetBy: i)]
}
subscript (i: Int) -> String {
if self.isEmpty {
return ""
}
if i > self.characters.count {
return ""
}
return String(self[i] as Character)
}
subscript (r: Range<Int>) -> String {
let start = self.index(self.startIndex, offsetBy: r.lowerBound)
let end = self.index(start, offsetBy: r.upperBound - r.lowerBound)
return self[Range(start ..< end)]
}
}

Related

Why does using a parameter name other the index result in Ambiguous use of 'subscript(_:)'

Take the two snippets below, the top one works fine but the bottom one results in
Ambiguous use of 'subscript(_:)'
using index ✅
extension Array {
subscript(i index: Int) -> (String, String)? {
guard let value = self[index] as? Int else {
return nil
}
switch (value >= 0, abs(value % 2)) {
case (true, 0): return ("positive", "even")
case(true, 1): return ("positive", "odd")
case(false, 0): return ("negative", "even")
case(false, 1): return ("negative", "odd")
default: return nil
}
}
}
Without using index ❌
extension Array {
subscript(i: Int) -> (String, String)? {
guard let value = self[i] as? Int else {
return nil
}
switch (value >= 0, abs(value % 2)) {
case (true, 0): return ("positive", "even")
case(true, 1): return ("positive", "odd")
case(false, 0): return ("negative", "even")
case(false, 1): return ("negative", "odd")
default: return nil
}
}
}
First, the name index is irrelevant to the problem; it could be any name.
The actual problem is that Array already has a subscript that takes an unlabeled Int.
Your first overload does not have the same input signature. Instead, it requires an argument label:
[1][i: 0] // ("positive", "odd")
You can still use an overload without a label…
extension Array where Element: BinaryInteger {
subscript(🫵: Int) -> (String, String) {
let value: Element = self[🫵]
return (
value >= 0 ? "positive" : "negative",
value.isMultiple(of: 2) ? "even" : "odd"
)
}
}
…but then, as is necessary within the subscript body itself, you'll need to always explicitly type the result, in order to access the overload from the standard library, because whatever you have in your own module is going to take precedence.
[1][0] // ("positive", "odd")
[1][0] as Int // 1
So, I recommend either using a subscript with a label, or a method.*
* What I would like to recommend is a named subscript. But Swift doesn't have them. You can emulate them with more types, however. Like this:
extension Array where Element: BinaryInteger {
struct InfoStrings {
fileprivate let array: Array
}
var infoStrings: InfoStrings { .init(array: self) }
}
extension Array.InfoStrings {
subscript(index: Int) -> (String, String) {
let value = array[index]
return (
value >= 0 ? "positive" : "negative",
value.isMultiple(of: 2) ? "even" : "odd"
)
}
}
[1].infoStrings[0]

Swift subscript with generic data type

I am trying to program a two-dimensional data storage struct for various data types. However, I am struggling with the subscript for setting the data due 'Cannot assign value of type 'T' to subscript of type 'T' errors. Any help is much appreciated!
struct dataMatrix<T> : Sequence, IteratorProtocol {
var rows: Int, columns: Int
var data: [T]
var position = 0
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
data = Array<T>()
}
func valueAt(column: Int, row: Int) -> T? {
guard column >= 0 && row >= 0 && column < columns else {
return nil
}
let indexcolumn = column + row * columns
guard indexcolumn < data.count else {
return nil
}
return data[indexcolumn]
}
}
subscript<T>(column: Int, row:Int) -> T?{
get{
return valueAt(column: column, row: row) as? T
}
set{
data[(column * row) + column] = (newValue as! T) // does not compile
}
}
// sequence iterator protorocl methods
mutating func next() -> String? {
if position <= data.count{
print(position)
defer { position += 1 }
return "\(position)"
}else{
defer {position = 0}
return nil
}
}
}
subscript<T>(column: Int, row:Int) -> T?{
defines a generic method with a type placeholder T which is unrelated to the generic type T of struct dataMatrix<T>. The solution is simple: Remove the type placeholder:
subscript(column: Int, row: Int) -> T? {
// ...
}
That makes also the type casts inside the getter and setter unnecessary. You only have to decide what to do if the setter is called with a nil argument (e.g.: nothing):
subscript(column: Int, row: Int) -> T? {
get {
return valueAt(column: column, row: row)
}
set {
if let value = newValue {
data[(column * row) + column] = value
}
}
}
Another option is to make the return type of the subscript method non-optional, and treat invalid indices as a fatal error (which is how the Swift Array handles it):
subscript(column: Int, row: Int) -> T {
get {
guard let value = valueAt(column: column, row: row) else {
fatalError("index out of bounds")
}
return value
}
set {
data[(column * row) + column] = newValue
}
}

How is the pullback defined for a function with an optional argument?

Here is a minimal example:
import _Differentiation
#differentiable(reverse)
func g(x: Double?) -> Double {
if x == nil {
return 0.0 // I don't care what this value is
}
else {
return x! * x!
}
}
#derivative(of: g)
func gVJP(x: Double?) -> (value: Double, pullback: (Double) -> Double?) {
let value = g(x: x)
func pullback(_ dOutput: Double) -> Double? {
if x == nil {
return nil // I don't care what this value is
}
else {
return dOutput * 2.0 * x!
}
}
return (value: value, pullback: pullback)
}
I get the following compiler error:
Function result's 'pullback' type does not match 'g(x:)'
1. 'pullback' does not have expected type '(Double.TangentVector) -> Optional<Double>.TangentVector' (aka '(Double) -> Optional<Double>.TangentVector')
I tried defining the return type of the pullback to be Optional<Double>.TangentVector, but that gave me errors that my pullback's return values were incompatible with return type 'Optional<Double>.TangentVector'.
The return values of pullback need to be cast to type Optional<Double>.TangentVector:
import _Differentiation
#differentiable(reverse)
func g(x: Double?) -> Double {
if x == nil {
return 0.0 // I don't care what this value is
}
else {
return x! * x!
}
}
#derivative(of: g)
func gVJP(x: Double?) -> (value: Double, pullback: (Double) -> Optional<Double>.TangentVector) {
let value = g(x: x)
func pullback(_ dOutput: Double) ->Optional<Double>.TangentVector {
if x == nil {
return Optional<Double>.TangentVector(nil) // I don't care what this value is
}
else {
return Optional<Double>.TangentVector(dOutput * 2.0 * x!)
}
}
return (value: value, pullback: pullback)
}

How can I extract numbers from string in Swift in a specific way

I'm struggling to extract numbers from a string in Swift. I'm doing the following:
let expression: String = "abc123aa223bb45"
for (indx, ch) in expression.enumerated() {
if ch.isLetter { continue }
else if ch.isNumber {
var val: Int = 0
while(indx < expression.count && ch.isNumber){
val = val * 10 + (ch.asciiValue - 48)
//how can I proceed and increment both indx and ch ...
}
// here I'm going to do smthing with every extracted number
}
}
Can somebody help me finish this problem I've reached?
I also use the extension
extension Character {
var asciiValue: Int {
get {
let s = String(self).unicodeScalars
return Int(s[s.startIndex].value)
}
}
}
as you can see in the posted fragment of code
The following code snippet will extract numbers from a String
let expression: String = "abc123aa223bb45"
let stringArray = expression.components(separatedBy: CharacterSet.decimalDigits.inverted)
for item in stringArray {
if let number = Int(item) {
print(number)
}
}
You could also make an extension of Int that has a function like
extension Int {
static func parse(from string: String) -> Int? {
return Int(string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined())
}
}
and can be use like this
let expression: String = "abc123aa223bb45"
if let number = Int.parse(from: expression) {
print(number)
}
I'm trying to write a program that evaluates expression with braces and operators: ^,+,-,/,*
But I'm having some issues ( I've done this many times with C++ and C# but I cannot manage to do it with swift. It really gives me a huge headache ):
import Foundation
extension Character {
var asciiValue: Int {
get {
let s = String(self).unicodeScalars
return Int(s[s.startIndex].value)
}
}
}
precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence }
infix operator ^^ : PowerPrecedence
func ^^ (radix: Double, power: Int) -> Double {
return (pow(Double(radix), Double(power)))
}
func calc(a: Double, b: Double, o: Character) -> Double {
switch o {
case "+":
return a + b
case "-":
return a - b
case "/":
return a / b
case "*":
return a * b
case "^":
return a ^^ Int(b)
default:
return 0
}
}
func nice(o: Character) -> Int {
if o == "-" || o == "+" { return 1 }
if o == "*" || o == "/" { return 2 }
if o == "^" { return 3 }
return 2020
}
func evaluate(expression: String) -> Double {
var vals = [Double]()
var ops = [Character]()
for (indx, ch) in expression.enumerated() {
if ch == " " { continue }
else if ch == "(" { ops.append(ch) }
else if ch.isNumber {
var val: Int = 0
while(indx < expression.count && ch.isNumber){
val = val * 10 + ch.asciiValue - 48 // gives strange error
//TODO increment indx and ch
}
vals.append(Double(val))
} else if ch == ")" {
while !ops.isEmpty && ops.last != "(" {
let val_2: Double = vals.popLast()!
let val_1: Double = vals.popLast()!
let op: Character = ops.popLast()!
vals.append(calc(a: val_1, b: val_2, o: op))
}
if !ops.isEmpty { _ = ops.popLast() } // opening brace
} else {
while(!ops.isEmpty && nice(o: ops.last!) >= nice(o: ch)){
let val_2: Double = vals.popLast()!
let val_1: Double = vals.popLast()!
let op: Character = ops.popLast()!
vals.append(calc(a: val_1, b: val_2, o: op))
}
ops.append(ch);
}
}
while !ops.isEmpty {
let val_2: Double = vals.popLast()!
let val_1: Double = vals.popLast()!
let op: Character = ops.popLast()!
vals.append(calc(a: val_1, b: val_2, o: op))
}
return vals.last!
}
let exp: String = "2^3+(2+3)"
print(evaluate(expression: exp))

Cannot invoke initializer for type 'Range<_>' with an argument list of type '(Range<String.Index>)'

Since Xcode 10 I receive an error message Cannot invoke initializer for type 'Range<_>' with an argument list of type '(Range<String.Index>)' at the return line in the code below, which is an extension used to get a substring when needed.
I have found another good answer given by Martin R at Cannot invoke initializer for type 'Range<String.Index>' with an argument list of type '(Range<String.Index>)', but didn't find a way yet to fix my problem.
extension String {
subscript (i: Int) -> Character { return self[index(startIndex, offsetBy: i)] }
subscript (i: Int) -> String { return String(self[i] as Character) }
subscript (r: Range<Int>) -> String {
let start = index(startIndex, offsetBy: r.lowerBound)
let end = index(startIndex, offsetBy: r.upperBound)
return String(self[Range(start ..< end)])
}
}