[Swift] Day15: String advanced and sperm symbols, swiftday15
String advanced and sperm symbol calculation String Length
We have two methods to calculate the length of a string.
Distance (str. startIndex, str. endIndex)
distanceIs defined as follows:
func distance<T : ForwardIndexType>(start: T, end: T) -> T.Distance
From the definition,distanceYou can enter the start and end points, and then return the distance between them. The passed parameters must beForwardIndexTypeProtocol.
Next let's take a look.StringOfstartIndexAndendIndex. Both indexes areString.IndexType, used to define the character position, it is compliantBidirectionalIndexTypeThis protocol, and this Protocol inherits fromForwardIndexTypeThis protocol, so it can be passed as a parameter.
CountElements (str)
countElementsIs defined as follows:
func countElements<T : _CollectionType>(x: T) -> T.Index.Distance
You only need_CollectionTypeType parameter. The return step is the index value of the input parameter. That is to say, it may not always return numbers or other values. This is to be explored.
Advance several units
People as their names,advanceIs to push the value forward several units and then return. For exampleadvance(1,2)That is, forward 1 to 2 units, and 3 is returned.
Definition:
func advance<T : ForwardIndexType>(start: T, n: T.Distance) -> T
With this, we can do a lot of things.
For example, to obtain characters:
var str = "Hello, WHY"str[advance(str.startIndex, 7)] // W
For example, to intercept a substring:
var str = "Hello, WHY"str[advance(str.startIndex, 7)...advance(str.startIndex, 9)] // WHY
Why do I need to setadvanceCan Return substrings? BecauseStringIt is defined as follows:
extension String : Sliceable { subscript (subRange: Range<String.Index>) -> String { get }}
The following parameter must beRange<String.Index>Type, whileadvanceReturns the type of the input parameter, that isString.Index, And...ReturnedRangeThe type meets the condition.
Some first and last operations
We can use the following functions to perform simple operations on the first and last elements:
Last (str) // get the last element first (str) // get the first element dropFirst (str) // remove the first element dropLast (str) // remove the last element
See the definition to find thatCollectionTypeYou can also input a number array:
var a = [1,2,3]last(a) // 3first(a) // 1dropFirst(a) // 2,3dropLast(a) // 1,2
Filter and others
We can usefilterFilter strings. For example, the following code removes the vowel in the string:
Filter (str ,{! Contains ("aeiou", $0)}) // remove the vowel
This is the same as the previous array usage.mapAndreduce:
map(str, { "$\($0)"})reduce(str,"",{ "\($0)-\($1)" })Returns the string range.
We can useindicesThe range of the returned string:
var str = "Hello, why"indices(str) // 0..<10
indicesThe function is defined as follows, as long as it is a set type as an input parameter:
func indices<C : CollectionType>(x: C) -> Range<C.Index>
Include or not
You can usecontainsCheck whether the Sub-string is included:
contains("Hello", "e") // true
Definition:
func contains<S : SequenceType where S.Generator.Element : Equatable>(seq: S, x: S.Generator.Element) -> Bool
As long as the element isEquatableYou can usecontainsCheck whether this element exists in the sequence. For example, array:
contains([1,2,3], 5) // false
Combination implementation in reverse order
We can use a variety of combinations to quickly implement the reverse string function:
var str = "Hello, why"var revStr = ""for _ in str { revStr.append(last(str)!) str = dropLast(str)}println(revStr) // yhw ,olleH
You can also usereserveFunction:
var str = "Hello, why"reverse(str)
Search for substrings in combination
We can use a set of combinations to search for substrings:
Extension String {// return the search result of the substring. Return the Range array func rangesOfString (findStr: String)-> [Range <String. index>] {// store the returned result var arr = [Range <String. index>] () // Storage Start position var startIndex = self. startIndex // if it contains the first character of the substring if contains (self, first (findStr )!) {// Get the start position startIndex = find (self, first (findStr )!)! // Initialize the Count var I = distance (self. startIndex, startIndex) // when I is smaller than the possible value (equal to the boundary condition, that is, the substring appears at the end) while I <= countElements (self) -countElements (findStr) {// truncate the substring var tempStr = self [advance (self. startIndex, I ).. <advance (self. startIndex, I + countElements (findStr)] // if the substring matches successfully if tempStr = findStr {// storage result arr. append (Range (start: advance (self. startIndex, I), end: advance (self. startIndex, I + countElements (findStr) // pushes the counter position to the end of the matching result to continue matching I = I + countElements (findStr )} I ++} return arr} "hello, why hello ". rangesOfString ("hello") // [0 .. <5, 11 .. <16]Sperm symbol>
Swift has a magic sperm symbol:~>. The definition is like this:
func ~><T : _ForwardIndexType>(start: T, rest: (_Advance, T.Distance)) -> Tfunc ~><T : _ForwardIndexType>(start: T, rest: (_Advance, (T.Distance, T))) -> Tfunc ~><T : _BidirectionalIndexType>(start: T, rest: (_Advance, T.Distance)) -> Tfunc ~><T : _BidirectionalIndexType>(start: T, rest: (_Advance, (T.Distance, T))) -> Tfunc ~><T : _RandomAccessIndexType>(start: T, rest: (_Advance, (T.Distance))) -> Tfunc ~><T : _RandomAccessIndexType>(start: T, rest: (_Advance, (T.Distance, T))) -> Tfunc ~><T : _RandomAccessIndexType>(start: T, rest: (_Distance, (T))) -> T.Distancefunc ~><T : _ForwardIndexType>(start: T, rest: (_Distance, T)) -> T.Distance
We can call it like this:
let advanceBy5 = _advance(5) // (_Advance, Int)1~>advanceBy5 // 6
This article: Tilde Arrow in Swift.
Well, I can't fully understand the sudden crash. Show your knees in the afternoon...
References
- A pure Swift method for returning ranges of a String instance
- A Look At Swift's Elusive ~> Operator
- Swift Standard Library