young
(rtSwift)
1
I need a method that can be called like this:
let s = "some string"
let a = lookingForSign(s)
// or in reverse:
let b = lookingForSign(s.reversed())
I think I need something that works on a BidirectionalCollection or Collection of Character:
class Foo {
...
// I'm not able to come up with the right signature here:
func lookingForSign<S: BidirectionalCollection>lookingForSign(_ text: S) -> String? where ??? { // how to define this?
// Element is Character...
guard let signIndex = text.prefix(while: { !$0.isASCIIDigit }).firstIndex(where: { allowedSigns.contains(String($0)) }) else {
return nil
}
return String(text[signIndex])
}
}
1 Like
tem
(GalaxySwift)
2
Try this:
func lookingForSign<S: BidirectionalCollection>(_ text: S) -> String?
where S.Element == Character
young
(rtSwift)
3

I thought I did that, guess not..
BTW: Collection works as well
thanks!
1 Like
Be mindful that Collection.reversed uses Sequence.reversed, which creates a new array and copies the entire collection.
1 Like
young
(rtSwift)
5
Ah, thank you!
In my case, since I don't want text.reversed() to create a new Array copying the original String over, I should stick to only allow BidirectionalCollection for my method?
I'm not sure if I am 100% understand:
for this call:
let b = lookingForSign(s.reversed())
if I define my func this way:
func lookForSign<S: Collection>(_ text: S) -> String? where S.Element == Character {
// is text here a new Array copying everything over from the original String?
// even though s was a String which is BidirectionalCollection?
}
vs.
func lookingForSign<S: BidirectionalCollection>(_ text: S) -> String?
where S.Element == Character {
// text here is a `ReversedCollection` which "reference" the original s String, no copying?
}
young
(rtSwift)
6
Okay, I'm wrong. For my case, either Collection or BidirectionalCollection end up with ReversedCollection<String>:
var greeting = "Hello, playground"
aaa(greeting.reversed())
bbb(greeting.reversed())
func aaa<S: BidirectionalCollection>(_ text: S) where S.Element == Character {
print(" >> aaa: ", type(of: text)) // >> aaa: ReversedCollection<String>
}
func bbb<S: Collection>(_ text: S) where S.Element == Character {
print(" >> bbb", type(of: text)) // >> bbb ReversedCollection<String>
}
Oh, I missed that you reversed the string outside of lookingForSign. In that case Swift will use a more specific version of reversed available to String, which are Sequence.reversed and BidirectionalCollection.reversed. Since BidiCol refines Seq, BidiCol.reversed are selected.
The problem I mention is more akin to this:
var greeting = "Hello, playground"
aaa(greeting)
bbb(greeting)
// Reverse inside
func aaa<S: BidirectionalCollection>(_ text: S) where S.Element == Character {
print(" >> aaa: ", type(of: text.reversed()))
}
func bbb<S: Collection>(_ text: S) where S.Element == Character {
print(" >> bbb: ", type(of: text.reversed()))
}
In this case, bbb.text can only use Sequence.reversed (it doesn't know that S: BidiCol, and reversed isn't a protocol requirement either).
1 Like
young
(rtSwift)
8
ok. so it's okay for my use case to use Collection conformance requirement.