Swift 3上的String和Character

概览

字符串如何遍历?
字符串如何操作(增删改)?
字符串如何比较?

本文主要关注的就是字符串的上面3点操作

环境说明

macOS Sierra 10.12.2
Xcode Version 8.2.1

如何遍历?

OC

先看看OC中如何对集合进行遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
NSArray *ss = @[@1,@2,@3];
// forI 提供外部索引,通过索引遍历集合
for (int i = 0; i < ss.count; ++i) {
NSLog(@"forI:%@",ss[i]);
}

// forin 通过内部迭代集合,不需要索引
for (NSNumber *s in ss) {
NSLog(@"forin:%@",s);
}

// block方式迭代
[ss enumerateObjectsUsingBlock:^(id _Nonnull s, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"enumerate:%@",s);
}];

遍历OC字符串的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
NSString *s = @"testString";

// forI
for (int i = 0; i < s.length; ++i) {
NSLog(@"%c",[s characterAtIndex:i]);
}

// Collection expression type 'NSString *' may not respond to 'countByEnumeratingWithState:objects:count:'
// NSString并没有实现NSFastEnumeration协议
// for (NSString *subs in s) {

// }

[s enumerateSubstringsInRange:NSMakeRange(0, s.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
NSLog(@"%@",substring);
}];

Swift

1
2
3
4
5
6
7
8
// - 摘自String.h iOS10.2
public struct String {

/// Creates an empty string.
public init()

...
}

由上可知:Swift中的字符串是一个结构体

结构体是值类型,作参数传递时是拷贝副本进行传递,保证原字符串不会被改变

查看上面的注释可以了解到String的一些知识点

NSString类无缝桥接

1
2
3
4
5
6
/// A Unicode string value.
///
/// A string is a series of characters, such as `"Swift"`. Strings in Swift are
/// Unicode correct, locale insensitive, and designed to be efficient. The
/// `String` type bridges with the Objective-C class `NSString` and offers
/// interoperability with C functions that works with strings.

用字面量初始化

1
2
3
4
5
/// You can create new strings using string literals or string interpolations.
/// A string literal is a series of characters enclosed in quotes.
///
/// let greeting = "Welcome!"
///
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/// Character View
/// --------------
///
/// A string's `characters` property is a collection of *extended grapheme
/// clusters*, which approximate human-readable characters. Many individual
/// characters, such as "é", "김", and "🇮🇳", can be made up of multiple Unicode
/// code points. These code points are combined by Unicode's boundary
/// algorithms into extended grapheme clusters, represented by Swift's
/// `Character` type. Each element of the `characters` view is represented by
/// a `Character` instance.
///
/// print(cafe.characters.count)
/// // Prints "9"
/// print(Array(cafe.characters))
/// // Prints "["C", "a", "f", "é", " ", "d", "u", " ", "🌍"]"
///
/// Each visible character in the `cafe` string is a separate element of the
/// `characters` view.

查看Stringcharacters属性

1
2
3
4
5
6
7
public struct CharacterView {
/// Creates a view of the given string.
public init(_ text: String)
}

/// A view of the string's contents as a collection of characters.
public var characters: String.CharacterView

Stringcharacters是一个字符集合

可以根据charactersString进行遍历操作

String.CharacterView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/// `String.CharacterView` is a collection of `Character`.
extension String.CharacterView : BidirectionalCollection {

/// A position in a string's `CharacterView` instance.
///
/// You can convert between indices of the different string views by using
/// conversion initializers and the `samePosition(in:)` method overloads.
/// The following example finds the index of the first space in the string's
/// character view and then converts that to the same position in the UTF-8
/// view:
///
/// let hearts = "Hearts <3 ♥︎ 💘"
/// if let i = hearts.characters.index(of: " ") {
/// let j = i.samePosition(in: hearts.utf8)
/// print(Array(hearts.utf8.prefix(upTo: j)))
/// }
/// // Prints "[72, 101, 97, 114, 116, 115]"
public struct Index : Comparable, CustomPlaygroundQuickLookable {

/// A custom playground Quick Look for this instance.
///
/// If this type has value semantics, the `PlaygroundQuickLook` instance
/// should be unaffected by subsequent mutations.
public var customPlaygroundQuickLook: PlaygroundQuickLook { get }
}

/// A type used to represent the number of steps between two indices, where
/// one value is reachable from the other.
///
/// In Swift, *reachability* refers to the ability to produce one value from
/// the other through zero or more applications of `index(after:)`.
public typealias IndexDistance = Int

/// The position of the first character in a nonempty character view.
///
/// In an empty character view, `startIndex` is equal to `endIndex`.
public var startIndex: String.CharacterView.Index { get }

/// A character view's "past the end" position---that is, the position one
/// greater than the last valid subscript argument.
///
/// In an empty character view, `endIndex` is equal to `startIndex`.
public var endIndex: String.CharacterView.Index { get }

/// Returns the next consecutive position after `i`.
///
/// - Precondition: The next position is valid.
public func index(after i: String.CharacterView.Index) -> String.CharacterView.Index

/// Returns the previous consecutive position before `i`.
///
/// - Precondition: The previous position is valid.
public func index(before i: String.CharacterView.Index) -> String.CharacterView.Index

/// Accesses the character at the given position.
///
/// The following example searches a string's character view for a capital
/// letter and then prints the character at the found index:
///
/// let greeting = "Hello, friend!"
/// if let i = greeting.characters.index(where: { "A"..."Z" ~= $0 }) {
/// print("First capital letter: \(greeting.characters[i])")
/// }
/// // Prints "First capital letter: H"
///
/// - Parameter position: A valid index of the character view. `position`
/// must be less than the view's end index.
public subscript(i: String.CharacterView.Index) -> Character { get }
}

由上面可以得知,forI方式的索引的数据类型由原来的int改成了String.CharacterView.Index

1
let s = "Swift"
  • forI方式
1
2
3
for i in 0..<s.characters.count {
print(s.characters[s.characters.index(s.startIndex, offsetBy: i)])
}
  • for-in方式
1
2
3
for c in s.characters {
print(c)
}
  • block方式
1
2
3
s.characters.forEach { (c) in
print(c)
}

如何操作(增删改)?

  • 可以用\(String)组合字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
/// String interpolations are string literals that evaluate any included
/// expressions and convert the results to string form. String interpolations
/// are an easy way to build a string from multiple pieces. Wrap each
/// expression in a string interpolation in parentheses, prefixed by a
/// backslash.
///
/// let name = "Rosa"
/// let personalizedGreeting = "Welcome, \(name)!"
///
/// let price = 2
/// let number = 3
/// let cookiePrice = "\(number) cookies: $\(price * number)."
///
  • 可以用*”+”*连接字符串
1
2
3
4
5
6
/// Combine strings using the concatenation operator (`+`).
///
/// let longerGreeting = greeting + " We're glad you're here!"
/// print(longerGreeting)
/// // Prints "Welcome! We're glad you're here!"
///
  • append…

  • removeAll( ) remove(at:…) …

1
2
3
4
5
// 直接赋值
s = "swift"

// 替换
s.replaceSubrange(s.index(s.startIndex,offsetBy:1)...s.index(s.startIndex, offsetBy: 4), with: "WIFT")

如何比较?

1
2
3
4
5
6
7
8
9
10
11
12
13
/// Comparing strings for equality using the equal-to operator (`==`) or a
/// relational operator (like `<` and `>=`) is always performed using the
/// Unicode canonical representation. This means that different
/// representations of a string compare as being equal.
///
/// let cafe1 = "Cafe\u{301}"
/// let cafe2 = "Café"
/// print(cafe1 == cafe2)
/// // Prints "true"
///
/// The Unicode code point `"\u{301}"` modifies the preceding character to
/// include an accent, so `"e\u{301}"` has the same canonical representation
/// as the single Unicode code point `"é"`.
1
2
3
4
5
6
7
8
9
10
11
12
extension String : Equatable {

/// Returns a Boolean value indicating whether two values are equal.
///
/// Equality is the inverse of inequality. For any values `a` and `b`,
/// `a == b` implies that `a != b` is `false`.
///
/// - Parameters:
/// - lhs: A value to compare.
/// - rhs: Another value to compare.
public static func ==(lhs: String, rhs: String) -> Bool
}
  • Unicode编码
  • 使用==进行比较
  • 内容比较

参考

MWeb图床配置 理解objc运行时四-运行时流程分析
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×