Swift 中的字符串和集合

Swift 是一门静态的强类型语言。它以简单、干净、可读性好等特点著称。
1、 为什么是静态语言?
  首先静态语言比之动态语言,更具有安全性。它不允许类型之间自动的进行转换,必须要显示的转换。Swift是类型安全的,它会在编译的时候就检查你的代码,任何类型不匹配时都会报错。这使得编程人员能够尽快捕获并尽可能早地在开发过程中修正错误。但是,这并不意味着你必须指定每一个常量和变量所声明的类型。如果不指定你需要的类型,Swift使用类型推导来指定出相应的类型。类型推导使编译器在编译的时候通过你提供的初始化值自动推导出特定的表达式的类型。类型推导使Swift比起C或Objective-C只需要更少的类型声明语句。常量和变量仍然显式类型,但大部分指定其类型的工作Swift已经为你完成了。当你声明一个常量或变量并给出初始值类型的时候,类型推导就显得特别有用。这通常是通过给所声明的常量或变量赋常值来完成的。
  例如:你要声明一个用户名字符串常量,并为他赋值叫“json”.

let userName = "son"

不必指定什么类型,在编译时会通过类型推导的机制将常量userName 自动设为 赋的值的类型。
  2、什么叫强类型语言?
即变量或者常量,必须要先定义然后才能使用,否则会报错。
好了 ,言归正传,下面给大家介绍下Swift 中的字符串和集合

字符与字符串

Swift集百家之长,吸收了主流语言Java、C、C++等的好的特性,所以它功能十分强大,今天我们就来看看它强大的字符串。
首先,我们带着这样几个问题去了解、理解swift的字符串。
1、swift字符串怎么初始化的?
2、swift字符串长度可变吗?
3、swift字符串是指针,还是实际的值?
4、swift有哪些特性?
下面,我来一一解答这些问题。
(1) swift 字符串的初始化有2种方式,这两种方式的结果都是一样的。我们来初始化一个空字符串。

var str1 = ""            // 第一种方式
var str2 = String()      // 第二种方式
var str3 = "hello word"  // 当初始化一个非空字符串时,可以这样

(2) swift字符串长度是可变的,当然这只针对于用var 定义的字符串,用let定义的字符串常量是不可变的。正因为这个特性,它可以和其他字符,字符串通过符号“ = ”、“ += ”组合成新的字符串。

var str1 = "hello"
var str2 = "world"
var str3:Character = "!"    // 这是定义字符的方式

var strs1 = str1 + str2     // 结果为“hello word”

(3)swift字符串 是实际的值,不是指针。当把字符串变量赋值给另一个值,它原来的值不变。当把字符串变量当作参数传递时,它也是一个实际的值。

var str1 = "你好"
var str2 =  str1   // 这时,str1的值还是“你好”

由此可见,它不是指针,是一个实际的值。

(4)swift字符串有哪些特性?它的比较机制,验证机制,遍历机制,转换机制,组合机制,都是它的特性。
 a、比较机制。字符串之间的比较是可以分多样的。
它比较完全相等时,用“==”来连接;
它比较前缀相等时,给定一个字符串前缀,然后用要比的字符串,调用hasPrefix方法,参数为给定的前缀;
它比较后缀相等时,给定一个字符串后缀,然后用要比的字符串,调用hasSuffix方法,参数为给定的后缀。
举个例子,我们学校在开兴趣班,要统计各个兴趣班的人数有多少?用这个就可以很容易的找出来。

let students = [
    "iOS,谢明,s3sj101",
    "android,胡军,s3jn95",
    "iOS,都美君,s3jn95",
    "技术支持,高小龙,s3jn92",
    "数据库,阿斯,s3jn92",
    "数据库,封剑,s3j101"
]

var ios = 0        // 定义ios班的人数
var android = 0    // 定义android班的人数
var technical = 0  // 定义技术支持班的人数
var database = 0   // 定义数据库班的人数

for student in students {
    if student.hasPrefix("iOS") {
        ios++
    }
    
    if student.hasPrefix("android") {
        android++
    }
    
    if student.hasPrefix("技术支持") {
        technical++
    }
    
    if student.hasPrefix("数据库") {
        database++
    }

}

print("报iOS班的人数:\(ios)")          // 2
print("报android班的人数:\(android)")  // 1
print("技术支持班的人数:\(technical)")  // 1
print("数据库班的人数:\(database)")     // 2

如果我们要统计各个原班有多少人,可以这样做:

let students = [
    "ios,谢明,s3sj101",
    "android,胡军,s3jn95",
    "ios,都美君,s3jn95",
    "技术支持,高小龙,s3jn92",
    "数据库,阿斯,s3jn92",
    "数据库,封剑,s3j101"]

var s3jn95 = 0   // 定义s3jn95班的人数
var s3jn92 = 0   // 定义s3jn92班的人数
var s3j101 = 0   // 定义s3j101班的人数

for student in students {
    
    if student.hasSuffix("s3jn95") {
        s3jn95++
    }
    
    if student.hasSuffix("s3jn92") {
        s3jn92++
    }
    
    if student.hasSuffix("s3j101") {
        s3j101++
    }
    
}

print("s3sj95班的人数:\(s3jn95)")  // 2
print("s3jn92班的人数:\(s3jn92)")  // 2
print("s3j101班的人数:\(s3j101)")  // 1

b:验证机制。判断一个字符串是不是为空,我们可以用isEmpty属性获取

var str = ""

if str.isEmpty {
    print("str是空字符串")  // 执行结果:str是空字符串
}
else {
    print("str是非空字符串")
}

c:遍历机制。我们知道,字符串是有字符组成,swift可以遍历字符串中的每个字符。

var str = "HelloWorld"

for i in str.characters {
    print(i)
}

执行结果会把每个字符遍历出来。
d:转换机制。它还支持字符串的大小写转换。通过uppercaseString和lowercaseString属性可以做到,我们来看看:

var str = "helloWorld"

var upper = ""
var lower = ""

upper = str.uppercaseString   // 定义一个存放转化为大写后的变量
lower = str.lowercaseString   // 定义一个存放转化为小写后的变量

print(upper)
print(lower)

然后分别输出就行了 ,很简单吧。。。
e:组合机制.组合机制是它很大的一个亮点,它的长度是可变的,因此也是可以组合的。这给我们的开发带来很大的遍历,是我们开发者的福音哦。
  这里就不举例了,他们之间可以通过“+”、“+=”、也可以通过一个合法的表达式生成新的字符串。最后,它还可以计算字符串的总长度,
  需要用到的方法是:countElements。参数为要计算的字符串本身。

获取字符串的长度

var str = "helloWorld"

// 获取字符集合,再获取集合的count属性
let count = str.characters.count // 10

两个字符串的拼接

let str1 = "Hello"
let str2 = "World"

let str3 = str1 + str2  //HelloWorld

字符串和其他数据类型的拼接

let name = "why"
let age = 18

let info = "my name is \(name),age is \(age)" // my name is why,age is 18

字符串的格式化

// 比如时间: 03:04
let min = 3
let second = 4

let time = String(format: "%02d:%02d", arguments:[min,second]) // "03:04"

字符串的截取

// 1.简单的方式是将String转成NSString来使用,在标识符后加 as NSString即可
let myStr = "HelloWorld"
var subStr = (myStr as NSString).substringFromIndex(5) // return "World"
subStr = (myStr as NSString).substringToIndex(5)       // return "Hello"
subStr = (myStr as NSString).substringWithRange(NSRange(location: 5, length: 5)) // return "World"

// 2.Swift截取方式

let str = "MyPlayground"
// 截取开始位置
let fromindex = str.startIndex.advancedBy(2)
let header = str.substringToIndex(fromindex) // retrun "My"

// 截取结束位置
let toindex = str.endIndex.advancedBy(-6)
let footer = str.substringToIndex(toindex) // return "MyPlay"

// 截取中间的字符串
let range = Range(start: str.startIndex.advancedBy(2), end: str.endIndex.advancedBy(-6))
let middle = str.substringWithRange(range) // return "Play"

数组

Swift提供了3种主要的集合类型,array,set,dictionary。本节介绍array。


数组是存储有序的相同类型的集合,相同的值可以多次出现在不同的位置。
注意:
  Swift的Array类型桥接Foundation的NSArray类
  数组类型简单语法
  Swift数组类型完整写作Array<Element>,Element是数组允许存储值的合法类型,你也可以简单的写作[Element]。尽管两种形式在功能上是一样的, 但是我们推荐较短的那种,而且在本文中都会使用这种形式来使用数组。

创建数组

// 创建一个空数组
var someInts = [Int]()
print("someInts is type [Int] with \(someInts.count) items.")  // return:0

需要注意的是,someInts变量的类型在初始化时推断为一个int类型,或者如果上下文已经提供类型信息,例如一个函数参数或者一个已经定义好类型的常量或者变量,我们也可以直接写作 [],而不需要加Int。

someInts.append(3)  // someInts now contains 1 value of type Int

someInts = []       // someInts is now an empty array, but is still of type [Int]

创建一个带有默认值的数组
  Swift 中的Array类型还提供了一个可以创建特定大小并且所有数据设置为相同的默认值的构造方法。我们可以把准备加入数组的item数量(count)和适当类型的初始值(repeatedValue)传入数组构造函数:

// 创建一个带有默认值的数组

// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]
var threeDoubles = [Double](count: 3, repeatedValue: 0.0)

2个数组合并为一个数组
通过+来实现2个数组合为一个新数组

// 2个数组合并为一个数组
// 通过+来实现2个数组合为一个新数组

//anotherThreeDoubles is of type [Double], and equals [2.5, 2.5, 2.5]
var anotherThreeDoubles = [Double](count: 3, repeatedValue: 2.5)

// sixDoubles is inferred as [Double], and equals [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
var sixDoubles = threeDoubles + anotherThreeDoubles
var shoppingList:[String] = ["Eggs","Milk"]

// 这里说明shoppingList是一个存储String类型的数组变量,而且只能存储String类型的值。它还可以简单的写作
var shoppingList2 = ["Eggs","Milk"]

数组的访问和修改

// 获取数组数据 - 下标法
// firstItem is equal to "Eggs
var firstItem = shoppingList[0]

// 添加数据 - 使用append(_:)方法在数组的结尾处添加一条新的数据。
shoppingList.append("Flour")

// 使用+=也可以向数组中添加若干条新的数据
// shoppingList now contains 4 items
shoppingList += ["Baking Powder"]
// shoppingList now contains 7 items
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]

// 使用insert(_:atIndex:)在指定位置插入新的数据
// shoppingList now contains 7 items
// "Maple Syrup" is now the first item in the list
shoppingList.insert("Maple Syrup", atIndex: 0)

// 修改数组 - 下标法修改其中一项值
shoppingList[0] = "Six eggs"

// 也可以修改指定范围内的值
// shoppingList now contains 6 items
shoppingList[4...6] = ["Bananas", "Apples"]

// removeAtIndex(_:)删除数组中指定位置的数据

// the item that was at index 0 has just been removed
// shoppingList now contains 6 items, and no Maple Syrup
// the mapleSyrup constant is now equal to the removed "Maple Syrup" string”
let mapleSyrup = shoppingList.removeAtIndex(0)

shoppingList

我们可以通过数组的方法和属性来访问和修改数组,或者下标语法。 使用数组的只读属性count来获取数组的count。
使用isEmpty判断数组是否为空。
我们不可以通过下标法来在数组的末尾处添加新的数据,因为index超出数组长度后是不合法的,会发生运行时错误
如果你像删除数组中最后一条数据,那么你应该使用removeLast(),而不应该使用removeAtIndex(),因为它不用查询数组的长度。

数组的遍历

你可以使用for-in'循环来遍历数组

// 你可以使用for-in'循环来遍历数组
for item in shoppingList {
    print(item)
}

如果我们同时需要每个数据项的值和索引值,可以使用全局enumerate函数来进行数组遍历。enumerate返回一个由每一个数据项索引值和数据值组成的键值对组。我们可以把这个键值对组分解成临时常量或者变量来进行遍历:

for (index,value) in shoppingList.enumerate() {
    print("Item \(index+1):\(value)")
}

// Item 1: Six eggs
// Item 2: Milk
// Item 3: Flour
// Item 4: Baking Powder
// Item 5: Bananas”

字典

字典是一种存储相同类型多重数据的存储器。每个值(value)都关联独特的键(key),键作为字典中的这个值数据的标识符。和数组中的数据项不同,字典中的数据项并没有具体顺序。
  字典写作Dictionary<Key, Value>。也可以写作[Key: Value]

// 创建空字典
// namesOfIntegers is an empty [Int: String] dictionary
var namesOfIntegers = [Int:String]()

// namesOfIntegers now contains 1 key-value pair
namesOfIntegers[16] = "sixteen"
namesOfIntegers

// namesOfIntegers is once again an empty dictionary of type [Int: String]
namesOfIntegers = [:]
namesOfIntegers

// 创建字典
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
airports

// 类型推断
var airports2 = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
airports2

airports["LHR"] = "London Heathrow"
airports

// 访问和修改
// Prints "The old value for DUB was Dublin.
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
    print("The old value for DUB was \(oldValue).")
}
airports

// removeValueForKey(_:)删除键值对
if let removedValue = airports.removeValueForKey("DUB") {
    print("The removed airport's name is \(removedValue).")
} else {
    print("The airports dictionary does not contain a value for DUB.")
}
airports

// 遍历
for (airportCode, airportName) in airports {
    print("\(airportCode): \(airportName)")
}

// YYZ: Toronto Pearson
// LHR: London Heathrow

for airportCode in airports.keys {
    print("Airport code: \(airportCode)")
}

// Airport code: YYZ
// Airport code: LHR

for airportName in airports.values {
    print("Airport name: \(airportName)")
}

// Airport name: Toronto Pearson
// Airport name: London Heathrow

// count返回字典的键值对数
// isEmpty判断字典是否为空

Sets

Sets是存储无序的相同类型的值,你可以在顺序不重要的情况下使用Sets来替代数组,或者当你需要同一个值在集合中只出现一次时。

Sets类型语法

写作Set<Element>,Element是sets允许存储的类型

// 创建并初始化一个空的set
var letters = Set<Character>()
print("letters is of type Set<Character> with \(letters.count) items.")
// Prints "letters is of type Set<Character> with 0 items.

// 如果可以推断出它元素的类型也可以写作
letters = []

// 通过数组字面量来创建set
var favoriteGenres:Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres has been initialized with three initial items

// 或者(因为可以推断为set<String>)
var favoriteGenres2:Set = ["Rock", "Classical", "Hip hop"]
// favoriteGenres2 has been initialized with three initial items
// 访问和修改
// count方法返回set的数据项数目
print("I have \(favoriteGenres.count) favorite music genres.")
// Prints "I have 3 favorite music genres.

// isEmpty判断set是否为空
// contains(_:)检查set对象是否包含特定的数据。
if favoriteGenres.contains("Funk") {
    print("I get up on the good foot.")
} else {
    print("It's too funky in here.")
}
// Prints "It's too funky in here.

// 添加新数据项
// insert(_:)向现有的set对象添加新的数据
favoriteGenres.insert("Jazz")
// favoriteGenres now contains 4 items

// 删除已有的数据项
// remove(_:)向现有的set对象删除已有的数据
if let removedGenre = favoriteGenres.remove("Rock") {
    print("\(removedGenre)? I'm over it.")
} else {
    print("I never much cared for that.")
}

// Prints "Rock? I'm over it.
// 遍历set
// 使用for in语句遍历set
for genre in favoriteGenres {
    print("\(genre)")
}

// Classical
// Jazz
// Hip hop
// set无序存储数据,使用sort()可以按到升序排序。

// intersect(_:)创意一个包含两set对象共有的数据的新的Set对象
// exclusiveOr(_:)创意一个不包含两set对象共有的数据的新的Set对象
// union(_:)创意一个包含两set对象所有的数据的新的Set对象
// subtract(_:)创意一个只存在其中一个已有的set类型数据的新的Set对象

let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]

oddDigits.union(evenDigits).sort()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

oddDigits.intersect(evenDigits).sort()
// []

oddDigits.subtract(singleDigitPrimeNumbers).sort()
// [1, 9]

oddDigits.exclusiveOr(singleDigitPrimeNumbers).sort()
// [1, 2, 9]

// ==操作符比较2个set的值是否全部相同
let houseAnimals: Set = ["🐶", "🐱"]
let farmAnimals: Set = ["🐮", "🐔", "🐑", "🐶", "🐱"]
let cityAnimals: Set = ["🐦", "🐭"]

houseAnimals.isSubsetOf(farmAnimals)    // true
farmAnimals.isSupersetOf(houseAnimals)  // true
farmAnimals.isDisjointWith(cityAnimals) // true
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,771评论 1 10
  • 一个字符串 是一系列字符的集合,例如hello, world和albatross。Swift的字符串是String...
    BoomLee阅读 2,386评论 0 3
  • 一个忙碌的诗人 光速敲打出一首新诗 他的目光在五寸五的屏幕上得意 “小河清清照我心 一座山后是一群起伏的山 山那边...
    Joker橙小K阅读 153评论 0 1
  • 嫁十年,年三十,以疾卒,在乾隆四十一年二月之十二日。诸姑兄弟哭之,感动邻人。于是彭绩始知柴米价,持门户,不能专精读...
    益坚阅读 548评论 0 0
  • 在《请回答1988》中,关于妈妈有这样的一段台词,“什么是妈妈?为了你可以放弃自尊的强大的存在,是代替神守护你的存...
    酸甜哈密瓜阅读 5,997评论 3 13