0

I am a newbie in Swift. I use Swift 5.1 I want to get a substring from a string but I was not able to. I already tried several solutions(here, here) but those didn't work for me.

I tried it like this :

Screenshot

func substring(x : Int, y : Int, s : String) -> String {
  let start = s.index(s.startIndex, offsetBy: x);
  let end   = s.index(s.startIndex, offsetBy: y);
  return s[start..<end];
}

print(substring(x: 0, y: 2, s: "abcde"))

/tmp/306AE87E-57C7-417C-B2EF-313A921E75B9.BuUdsc/main.swift:6:11: error: subscript 'subscript(_:)' requires the types 'String.Index' and 'Int' be equivalent return s[start..(bounds: R) -> String where R : RangeExpression, R.Bound == Int { get } ^

I really appreciate your help. Thank you.

tomerpacific
  • 4,704
  • 13
  • 34
  • 52

3 Answers3

3

This is again one of those confusing error messages that doesn't tell you want you actually did wrong.

You should do this:

return String(s[start..<end])

This is because the subscript that takes a Range<String.Index> actually returns a Substring, but your method returns a String, so you have to convert it before returning.

Speculation on why the error message is outputted:

Seeing that the method returns a String, the Swift compiler tries to find a subscript which returns a String, and some how it found one (I couldn't), but that overload only works on types with the Index associated type being Int.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • The wrong error message is a bug, compare https://stackoverflow.com/questions/60095464/why-does-string-subscript-require-the-types-string-index-and-int-to-be-e#comment106288936_60095872. – Martin R Feb 10 '20 at 09:40
2

Your code is mostly fine but Swift is messing up the error message. I tried your code in the Xcode 11.4 beta with Swift 5.2 better error diagnostics and it complained that the return type String is incorrect because s[start..<end] gives you a Substring. You can either change the return type:

func substring(x : Int, y : Int, s : String) -> Substring {
  let start = s.index(s.startIndex, offsetBy: x)
  let end   = s.index(s.startIndex, offsetBy: y)
  return s[start..<end]
}

print(substring(x: 0, y: 2, s: "abcde"))

or convert the substring to a string:

func substring(x : Int, y : Int, s : String) -> String {
  let start = s.index(s.startIndex, offsetBy: x)
  let end   = s.index(s.startIndex, offsetBy: y)
  return String(s[start..<end])
}

print(substring(x: 0, y: 2, s: "abcde"))

Sidenote: the ; is not required in Swift and it's a convention to not use it unless you want to have multiple statements on a single line.

donnywals
  • 7,241
  • 1
  • 19
  • 27
0

As your function returns a String, you need to convert s[start..<end] which is Substring to String.

func substring(x : Int, y : Int, s : String) -> String {
  let start = s.index(s.startIndex, offsetBy: x);
  let end   = s.index(s.startIndex, offsetBy: y);
    return String(s[start..<end])
}

print(substring(x: 0, y: 2, s: "abcdefghijklmnopqrstuvwxyz"))

Output:

ab
Keshu R.
  • 5,045
  • 1
  • 18
  • 38