最近写完了Swift 3.0教程 ,在接下来这段时间,继续写Foundation 的教程,帮助大家更加深入,系统的学习Foundation 框架,可能会持续一段时间,希望有兴趣的朋友加个关注!
var str = String()
var str1 = ""
var cString:[CChar] = [67, 97, 102, -61, -87, 0]
var str1 = String(cString: cString)
var dog: Character = "?"
var str = String(dog)
var validUTF8: [CChar] = [67, 97, 102, -61, 0]
let str = String(validatingUTF8: validUTF8)
print(str)
提示:
如果里面包含一个非法的编码,初始化失败返回nil
var validUTF8: [UInt8] = [67, 97, 102, 195, 0]
validUTF8.withUnsafeBufferPointer { ptr in
let s = String.decodeCString(ptr.baseAddress,as: UTF8.self,
repairingInvalidCodeUnits: true)
输出结果:
Optional(("Caf�", true))
提示:
1.使用这个方法时一定要注意字符数组元素必须为UInt8 2.参数repairingInvalidCodeUnits 设置为true的意思,表示如果出现编码错误可以使用"\u{FFFD}" 进行替换,如果为false ,一旦出现错误的编码,则直接返回nil
str.isEmpty
var str1 = "Ku1991Zou01Ti2Ya8"
str1.hasPrefix("Ku")
var str1 = "Ku1991Zou01Ti2Ya8"
str1.characters.count // 18
var str1 = "Ku1991Zou01Ti2Ya8我"
str1.utf8.count
str1.utf16.count
str1.unicodeScalars.count
输出结果:
20 18 18
var str1 = "Ku1991Zou01Ti2Ya8我"
let index = str1.index(str1.startIndex, offsetBy: 8)
print(str1[index])
运行结果:
u
还有一个方法
str1.index(str1.startIndex, offsetBy: 30, limitedBy: str1.endIndex)
注意两者的区别:
第一个方法如果索引访问超过字符串的长度的话,系统会报错崩溃,但是第二种不会报错,会返回一个可选值nil
思考:如果索引时有条件的话,我们应该怎么做呢?看下面的例子
问题: 在一个字符串中找到第一个能被3整除的数字
let nums = "1,3,5,6,7,8,9"
let index = nums.characters.index { (char) -> Bool in
if let num = Int(char.description){
if num%3 == 0{
return true
}
return false
}
return false
}
print(nums.characters[index!])
let str = "werwer我"
print(str.unicodeScalars.first?.isASCII)
print(str.unicodeScalars.last?.isASCII)
运行结果:
true false
let word = "Backwards"
for char in word.characters.reversed() {
print(char, terminator="")
}
// Prints "sdrawkcaB"
class Student{
var name = "大?"
var age = 23
}
let studentDescribing = String(describing: Student())
print(studentDescribing)
输出结果:
Student
提示:
显然这不是我们想要的结果,我们需要输出里面属性信息,怎么办呢? 很简单,按照下面的步骤做
//1.第一步 让对象遵守协议 CustomStringConvertible
class Student:CustomStringConvertible{
var name = "大?"
var age = 23
//2.第二步实现协议
var description: String{
return name + "\(age)"
}
}
运行结果
大?23
当然我们实现了CustomStringConvertible 协议也可以使用下面的方法查看对象的描述内容
// 映射
let studentReflecting = String(reflecting: Student())
// 直接输出
print(Student())
var str = "apple"
str.append("?") // 追加一个字符
str.append(",banana")// 追加一个字符串
str += "?" // 简约写法
str.append(contentsOf: ["1","2","3"])// 追加元素为字符串的数组
let newString = str.appending("new") // 追加一个字符串生成一个新的字符串
运行过程
"apple" "apple?" "apple?,banana" "apple?,banana?" "apple?,banana?123 "apple?,banana?123new
let str = "A,B,C,D,e,f,g,h"
var lowercase = str.lowercased()
var upperCase = str.uppercased()
运行:
"A,B,C,D,e,f,g,h" "a,b,c,d,e,f,g,h" "A,B,C,D,E,F,G,H"
var str = "?,?,?,?,?, ?,?,?"
for c in str.characters{
print(c)
}
for (n, c) in "Swift".characters.enumerated() {
print("\(n): '\(c)'")
}
// Prints "0: 'S'"
// Prints "1: 'w'"
// Prints "2: 'i'"
// Prints "3: 'f'"
// Prints "4: 't'"
var str = "?,?,?,?,?, ?,?,?"
// 首先将字符串进行分割
let characters = str.characters.split { (c) -> Bool in
c == ","
}
// 然后进行map初始化
let array = characters.map { (s) -> String in
return String.init(s)
}
运行结果:
["?", "?", "?", "?", "?", " ?", "?", "?"]
由于swift强大的类型推断能力,我们一气呵成的写法如下
let array = str.characters.split(whereSeparator: { $0 == "," })
.map(String.init)
a.需求: 剔除掉非ascii 编码的字符
let favemoji = "My favorite emoji is ?"
if let i = favemoji.utf16.index(where: { $0 >= 128 }) {
let asciiPrefix = String(favemoji.utf16.prefix(upTo: i))
print(asciiPrefix)
}
运行结果:
Optional("My favorite emoji is ")
b.需求: 从第一个位置开始截取6个字符
let favemoji = "My favorite emoji is ?"
let startIndex = favemoji.index(favemoji.startIndex, offsetBy: 1)
let endIndex = favemoji.index(favemoji.startIndex, offsetBy: 6)
print(favemoji[startIndex...endIndex])
c.替换字符串中指定的字符串
var favemoji = "My favorite emoji is ?"
favemoji = favemoji.replacingOccurrences(of: "My", with: "")
print(favemoji)
需求: 找出字符串中的数字放到一个新的数组中, 并从字符串中过滤掉这些数字
var str1 = "Ku1991Zou01Ti2Ya8"
let nums = str1.withMutableCharacters { (chars) -> [Int] in
return chars.map({ (c) -> Int? in
if let num = Int(c.description){
chars.remove(at:chars.index(of: c)!)
return num
}
return nil
}).filter({$0 != nil}).map({ (num) -> Int in
return num!
})
}
print(str1)
print(nums)
运行结果:
KuZouTiYa [1, 9, 9, 1, 0, 1, 2, 8]
提示:
1.首先map,将数字从当前字符串中移除,如果是数字类型则返回,不是数字的字符返回nil 2.这时候,我们的数组里面的值是可选类型,我们通过filter过滤掉nil 得到没有nil的可选值数组,此时再map一下,将可选值值编程非可选值
let favemoji = "My favorite emoji is ?"
if let i = favemoji.utf16.index(where: { $0 >= 128 }) {
let asciiPrefix = String(favemoji.utf16.prefix(upTo: i))
print(asciiPrefix)
}
输出:
"My favorite emoji is "
let snowy = "❄️ Let it snow! ☃️"
let nsrange = NSRange(location: 3, length: 12)
if let r = nsrange.toRange() {
let start = snowy.utf16.index(snowy.utf16.startIndex, offsetBy: r.lowerBound)
let end = snowy.utf16.index(snowy.utf16.startIndex, offsetBy: r.upperBound)
let substringRange = start..<end
print(snowy.utf16[substringRange])
}
输出:
Let it snow!
var dog: [UInt8] = [97,98,99,100,0]
var str = String(cString:dog)
str.withCString { (ptr) in
// 获取字符串的指针地址
print(ptr)
}
运行结果:
0x00006080000498f0
var str = "\u{FFFD}"
print(str)
执行结果:
"�"
var cString:[CChar] = [67,97,102,-61,0]
var str1 = String(cString: cString)
提示:
-61 就是非法的UTF-8编码,但是(-61,-87就是正确的编码),代表:é
运行结果:
"Caf�"
var validUTF8: [CChar] = [67, 97, 102, -61, -87, 0]
validUTF8.withUnsafeBufferPointer { ptr in
// 获取指针的地址
print(ptr.baseAddress!)
// 通过指针地址初始化数组
let s = String(cString: ptr.baseAddress!)
print(s)
return
}
指定结果:
0x000060800004dbe0 Café
let x = validUTF8.withUnsafeMutableBufferPointer { (ptr) -> CChar in
//获取指针的值
print(ptr.baseAddress!.pointee)
// 修改指针的地址,让其向后移动一位
let s = String(cString: (ptr.baseAddress?.advanced(by: 1))!)
print(s)
return (ptr.baseAddress?.pointee)!
}
运行结果:
afé 67
var num = 10
String(num,radix:2)
String(num,radix:16,uppercase: true) //输出大写
String(num,radix:8)
String(num,radix:10)
运行:
"1010" "A" "12" "10"
注意:
要求进制至少是2,至多36
var str1 = "Ku"
let vowels: Set<Character> = ["a", "e", "i", "o", "u"]
var x = str1.characters.lazy.filter { a in
print("方法执行了")
return vowels.contains(a)}
print("哈哈")
print(String(x))
运行结果:
哈哈 方法执行了 方法执行了 方法执行了 方法执行了 u
??江湖求援:
懒加载时,闭包函数会执行四次,但在普通加载的时候,只执行两次,具体原因不详,如果您知道为什么会这样,烦请留言,感激涕零?!
let hearts = "Hearts <3 ♥︎ ?"
if let i = hearts.characters.index(of: " ") {
// 一定要注意,这一步决定不能少
let j = i.samePosition(in: hearts.utf8)
// 的参数类型为 String.UTF8View.Index,所以通过上面的函数获取到对应的索引
print(hearts.utf8.suffix(from: j))
}
运行:
<3 ♥︎ ?
struct ASCIILogger: TextOutputStream {
mutating func write(_ string: String) {
let ascii = string.unicodeScalars.lazy.map { scalar in
scalar == "♡" || scalar == "♢"
? "✌️"
: scalar.escaped(asASCII: true)
}
print(ascii.joined(separator: ""))
}
}
let s = "Swift ♡ and ObjectC ♢"
print(s)
var asciiLogger = ASCIILogger()
print(s, to: &asciiLogger)
运行结果:
Swift ♡ and ObjectC ♢ Swift ✌️ and ObjectC ✌️ \n
let s1 = "They call me 'Bell'"
let s2 = "They call me 'Stacey'"
print(strncmp(s1, s2, 14))
print(strncmp(s1, s2, 15))
运行结果:
0 -17
a.第一种
let lowercase = "a"..."z"
print(lowercase.contains("z"))
b.更优雅的写法
if "A"..."Z" ~= "H" {
print("H")
}