Swift String与Array
string内存分配
字符小于等于15个时候
var str1 = "0123456789"
字符串长度 <= 0XF,字符串直接存放在str1变量的内存中
字符大于15个时候
var str2 = "0123456789ABCDEFGHIJ"
字符串的地址值存放在__TEXT.cstring中(常量区)
使用append的情况
str1.appended("ABCDE")
str1.appended("F")
由于字符串长度小于 <=0XF,所以字符串内容依然存放在str1变量的内存中
String基础
String创建
// 字符串字面量
let str1 = "Hello, World!"
let str2 = "Swift"
// 空字符串
let emptyString1 = ""
let emptyString2 = String()
// 多行字符串
let multiline = """
This is a
multiline string
with multiple lines
"""
// 字符串插值
let name = "Swift"
let version = 5.0
let info = "Welcome to \(name) \(version)"
字符串属性
let text = "Hello, Swift!"
// 长度
print(text.count) // 13
// 是否为空
print(text.isEmpty) // false
// 首字符和尾字符
print(text.first) // Optional("H")
print(text.last) // Optional("!")
String操作
字符串拼接
let str1 = "Hello"
let str2 = "World"
// 使用 + 操作符
let result1 = str1 + ", " + str2 + "!"
// 使用 += 操作符
var greeting = "Hello"
greeting += ", World!"
// 使用字符串插值
let result2 = "\(str1), \(str2)!"
字符串比较
let str1 = "Hello"
let str2 = "hello"
let str3 = "Hello"
// 相等比较
print(str1 == str3) // true
print(str1 == str2) // false
// 大小写不敏感比较
print(str1.lowercased() == str2.lowercased()) // true
// 前缀和后缀检查
print(str1.hasPrefix("He")) // true
print(str1.hasSuffix("lo")) // true
String索引
索引操作
let str = "Hello, Swift!"
// 开始和结束索引
let startIndex = str.startIndex
let endIndex = str.endIndex
// 偏移索引
let secondChar = str[str.index(after: startIndex)]
let thirdChar = str[str.index(startIndex, offsetBy: 2)]
// 字符范围
let range = str.index(startIndex, offsetBy: 0)...str.index(startIndex, offsetBy: 4)
let hello = str[range] // "Hello"
子字符串
let str = "Hello, Swift Programming!"
// 获取子字符串
let hello = str.prefix(5) // "Hello"
let programming = str.suffix(12) // "Programming!"
// 使用范围
let startIndex = str.index(str.startIndex, offsetBy: 7)
let endIndex = str.index(str.startIndex, offsetBy: 11)
let swift = str[startIndex..<endIndex] // "Swift"
String方法
常用方法
let text = " Hello, Swift! "
// 大小写转换
print(text.lowercased()) // " hello, swift! "
print(text.uppercased()) // " HELLO, SWIFT! "
print(text.capitalized) // " Hello, Swift! "
// 去除空白
print(text.trimmingCharacters(in: .whitespaces)) // "Hello, Swift!"
// 替换
print(text.replacingOccurrences(of: "Swift", with: "iOS")) // " Hello, iOS! "
// 分割
let words = text.trimmingCharacters(in: .whitespaces).components(separatedBy: " ")
print(words) // ["Hello,", "Swift!"]
高级字符串操作
let text = "Swift is awesome!"
// 包含检查
print(text.contains("Swift")) // true
print(text.contains("iOS")) // false
// 查找
if let range = text.range(of: "awesome") {
print("Found at: \(range)")
}
// 正则表达式
let emailPattern = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let email = "test@example.com"
print(email.range(of: emailPattern, options: .regularExpression) != nil) // true
Array基础
Array创建
// 数组字面量
let numbers = [1, 2, 3, 4, 5]
let strings = ["apple", "banana", "orange"]
// 空数组
let emptyArray1: [Int] = []
let emptyArray2 = [Int]()
let emptyArray3 = Array<Int>()
// 重复元素数组
let zeros = Array(repeating: 0, count: 5) // [0, 0, 0, 0, 0]
// 范围数组
let range = Array(1...5) // [1, 2, 3, 4, 5]
Array属性
let numbers = [1, 2, 3, 4, 5]
// 数量
print(numbers.count) // 5
// 是否为空
print(numbers.isEmpty) // false
// 首元素和尾元素
print(numbers.first) // Optional(1)
print(numbers.last) // Optional(5)
// 索引范围
print(numbers.indices) // 0..<5
Array操作
添加元素
var numbers = [1, 2, 3]
// 追加单个元素
numbers.append(4)
print(numbers) // [1, 2, 3, 4]
// 追加多个元素
numbers.append(contentsOf: [5, 6, 7])
print(numbers) // [1, 2, 3, 4, 5, 6, 7]
// 插入元素
numbers.insert(0, at: 0)
print(numbers) // [0, 1, 2, 3, 4, 5, 6, 7]
// 插入多个元素
numbers.insert(contentsOf: [-2, -1], at: 0)
print(numbers) // [-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
删除元素
var numbers = [1, 2, 3, 4, 5]
// 删除指定索引元素
let removed = numbers.remove(at: 2)
print(removed) // 3
print(numbers) // [1, 2, 4, 5]
// 删除第一个元素
let first = numbers.removeFirst()
print(first) // 1
print(numbers) // [2, 4, 5]
// 删除最后一个元素
let last = numbers.removeLast()
print(last) // 5
print(numbers) // [2, 4]
// 删除所有元素
numbers.removeAll()
print(numbers) // []
修改元素
var numbers = [1, 2, 3, 4, 5]
// 修改单个元素
numbers[0] = 10
print(numbers) // [10, 2, 3, 4, 5]
// 修改范围元素
numbers[1...3] = [20, 30, 40]
print(numbers) // [10, 20, 30, 40, 5]
// 替换范围
numbers.replaceSubrange(0...1, with: [100, 200])
print(numbers) // [100, 200, 30, 40, 5]
Array方法
遍历方法
let numbers = [1, 2, 3, 4, 5]
// for-in 循环
for number in numbers {
print(number)
}
// forEach 方法
numbers.forEach { number in
print(number)
}
// enumerated 方法
for (index, value) in numbers.enumerated() {
print("Index: \(index), Value: \(value)")
}
转换方法
let numbers = [1, 2, 3, 4, 5]
// map - 转换每个元素
let doubled = numbers.map { $0 * 2 }
print(doubled) // [2, 4, 6, 8, 10]
// compactMap - 过滤nil值
let strings = ["1", "2", "abc", "4", "5"]
let validNumbers = strings.compactMap { Int($0) }
print(validNumbers) // [1, 2, 4, 5]
// flatMap - 展平数组
let arrays = [[1, 2], [3, 4], [5, 6]]
let flattened = arrays.flatMap { $0 }
print(flattened) // [1, 2, 3, 4, 5, 6]
过滤和查找
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// filter - 过滤元素
let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers) // [2, 4, 6, 8, 10]
// first(where:) - 查找第一个符合条件的元素
let firstEven = numbers.first(where: { $0 % 2 == 0 })
print(firstEven) // Optional(2)
// contains - 检查是否包含元素
print(numbers.contains(5)) // true
print(numbers.contains(15)) // false
// allSatisfy - 检查所有元素是否都满足条件
print(numbers.allSatisfy { $0 > 0 }) // true
聚合方法
let numbers = [1, 2, 3, 4, 5]
// reduce - 聚合操作
let sum = numbers.reduce(0) { result, number in
return result + number
}
print(sum) // 15
// 简化写法
let sum2 = numbers.reduce(0, +)
print(sum2) // 15
// 最大值和最小值
print(numbers.max()) // Optional(5)
print(numbers.min()) // Optional(1)
// 排序
let shuffled = [3, 1, 4, 1, 5, 9, 2, 6]
let sorted = shuffled.sorted()
print(sorted) // [1, 1, 2, 3, 4, 5, 6, 9]
let sortedDescending = shuffled.sorted(by: >)
print(sortedDescending) // [9, 6, 5, 4, 3, 2, 1, 1]
高级用法
数组分组
let words = ["apple", "banana", "apricot", "blueberry", "cherry"]
// 按首字母分组
let grouped = Dictionary(grouping: words) { $0.first! }
print(grouped)
// ["a": ["apple", "apricot"], "b": ["banana", "blueberry"], "c": ["cherry"]]
数组去重
let numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
// 使用Set去重
let uniqueNumbers = Array(Set(numbers))
print(uniqueNumbers) // [2, 3, 1, 4] (顺序可能不同)
// 保持顺序去重
let uniqueOrderedNumbers = numbers.reduce([]) { result, number in
return result.contains(number) ? result : result + [number]
}
print(uniqueOrderedNumbers) // [1, 2, 3, 4]
数组分割
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// 分割成两部分
let (evenNumbers, oddNumbers) = numbers.reduce(([], [])) { result, number in
if number % 2 == 0 {
return (result.0 + [number], result.1)
} else {
return (result.0, result.1 + [number])
}
}
print(evenNumbers) // [2, 4, 6, 8, 10]
print(oddNumbers) // [1, 3, 5, 7, 9]
性能优化
预分配容量
// 好的做法:预分配容量
var numbers = [Int]()
numbers.reserveCapacity(1000)
for i in 0..<1000 {
numbers.append(i)
}
// 避免:频繁扩容
var numbers2 = [Int]()
for i in 0..<1000 {
numbers2.append(i) // 可能会多次扩容
}
使用合适的方法
let numbers = [1, 2, 3, 4, 5]
// 好的做法:使用 contains
if numbers.contains(3) {
print("Found")
}
// 避免:使用 filter
if !numbers.filter({ $0 == 3 }).isEmpty {
print("Found")
}
// 好的做法:使用 first(where:)
if let first = numbers.first(where: { $0 > 3 }) {
print("Found: \(first)")
}
// 避免:使用 filter + first
if let first = numbers.filter({ $0 > 3 }).first {
print("Found: \(first)")
}
实践示例
文本处理
func processText(_ text: String) -> [String: Any] {
let words = text.lowercased()
.components(separatedBy: .punctuationCharacters)
.joined()
.components(separatedBy: .whitespaces)
.filter { !$0.isEmpty }
let wordCount = words.count
let uniqueWords = Set(words)
let wordFrequency = Dictionary(grouping: words) { $0 }
.mapValues { $0.count }
return [
"wordCount": wordCount,
"uniqueWordCount": uniqueWords.count,
"wordFrequency": wordFrequency
]
}
let text = "Hello, world! This is a test. Hello again!"
let result = processText(text)
print(result)
数据过滤和排序
struct Person {
let name: String
let age: Int
let city: String
}
let people = [
Person(name: "Alice", age: 25, city: "New York"),
Person(name: "Bob", age: 30, city: "London"),
Person(name: "Charlie", age: 35, city: "New York"),
Person(name: "David", age: 28, city: "Paris")
]
// 过滤和排序
let youngPeopleInNY = people
.filter { $0.age < 30 && $0.city == "New York" }
.sorted { $0.age < $1.age }
print(youngPeopleInNY)
// [Person(name: "Alice", age: 25, city: "New York")]
最佳实践
1. 选择合适的数据结构
// 好的做法:频繁查找用Set
let validIds: Set = [1, 2, 3, 4, 5]
if validIds.contains(userId) {
// 处理
}
// 避免:频繁查找用Array
let validIds = [1, 2, 3, 4, 5]
if validIds.contains(userId) {
// 处理
}
2. 避免不必要的拷贝
// 好的做法:使用Substring
func processSubstring(_ text: String) -> String {
let substring = text.prefix(10)
return String(substring) // 只在需要时转换
}
// 避免:过早转换
func processSubstring(_ text: String) -> String {
let substring = String(text.prefix(10)) // 不必要的拷贝
return substring
}
3. 合理使用map和filter
// 好的做法:链式操作
let result = numbers
.filter { $0 > 0 }
.map { $0 * 2 }
.sorted()
// 避免:多次遍历
let positive = numbers.filter { $0 > 0 }
let doubled = positive.map { $0 * 2 }
let sorted = doubled.sorted()
📝 重要提示
- String是值类型:修改字符串会创建新的实例
- String索引:不支持整数索引,需要使用String.Index
- Array性能:插入和删除操作的时间复杂度取决于位置
- 内存管理:大数组操作时注意内存使用
- 类型安全:Swift的类型系统保证操作的安全性
🎯 总结
String和Array是Swift中最基础和最重要的数据类型。掌握它们的用法对于Swift编程至关重要:
- String:提供了丰富的文本处理功能
- Array:提供了强大的集合操作能力
- 性能考虑:选择合适的方法和数据结构
- 类型安全:利用Swift的类型系统避免错误
通过合理使用这些特性,可以编写出高效、安全的Swift代码。
本文档基于Swift 5.0+版本,涵盖了String和Array的核心用法和最佳实践。