iOS:Swift 数组、字典、集合

数组(Array)是有序数据集。

集合(Set)是无序且无重复数据集。

字典(Dictionary)是无序键值对的集。

注意: Swift 的 Array、Set 和 Dictionary 类型被实现为泛型集合

数组

简单创建

var beatles = ["John", "Paul", "George", "Ringo"]
let numbers = [4, 8, 15, 16, 23, 42]
var temperatures = [25.3, 28.2, 26.4]

let 创建的是不可变数组

var 创建的是可变数组

数据读取

print(beatles[0])
print(numbers[1])
print(temperatures[2])

输出:
John
8
26.4

注意:使用索引读取数据时,必须保证索引处存在,否则崩溃

数据添加

beatles.append("Allen")
beatles.append("Adrian")

注意:数组内只能包含一种类型的数组

temperatures.append("Chris")是不允许的。

明确类型的创建

var scores = Array<Int>() 或 var scores = [Int]() 均可
scores.append(100)
scores.append(80)
scores.append(85)
print(scores[1])

简单函数使用

var characters = ["Lana", "Pam", "Ray", "Sterling"]
// 数组长度
print(characters.count)

// 移除指定位置的元素
characters.remove(at: 2)
print(characters.count)

// 移除全部
characters.removeAll()
print(characters.count)

// 是否包含
print(characters.contains("Frozen"))

高阶函数使用

排序

可以在sorted内根据需求实现排序规则

// 基本数据类型排序
let cities = ["London", "Tokyo", "Rome", "Budapest"]
print(cities.sorted())

输出:
["Budapest", "London", "Rome", "Tokyo"]

自定义类排序
struct HFModel {
    var testAge: Int
}
let models = [HFModel(testAge: 10), HFModel(testAge: 30), HFModel(testAge: 90)]
let sortedModels = models.sorted{ m1, m2 in
    return m1.testAge > m2.testAge
}
/**
  [SwiftEnumDemo.HFModel(testAge: 90),
 SwiftEnumDemo.HFModel(testAge: 30), SwiftEnumDemo.HFModel(testAge: 10)]
*/
print(sortedModels)

数组的遍历

let presidents = ["Bush", "Obama", "Trump", "Biden"]
for item in presidents {
    print(item)
}

// 需要每个数据项的值和索引值,可以使用enumerated()方法来进行数组遍历
for (index, value) in presidents.enumerated() {
   print("Item \(String(index + 1)): \(value)")
}

// 遍历数组,但是不包括第一个元素
/**
 Obama
 Trump
 Biden
 */
for item in presidents.dropFirst(){
    print(item)
}
print("- - - - - - -")
// 遍历数组,但是不包括最后一个或几个元素
/**
 Bush
 Obama
 Trump
 */
for item in presidents.dropLast(){
    print(item)
}
print("- - - - - - -")

// 遍历数组,但是不包括最后一个或几个元素
/**
 Bush
 Obama
 */
for item in presidents.dropLast(2){
    print(item)
}

反转数组

let presidents = ["Bush", "Obama", "Trump", "Biden"]
print(presidents)

let reversedPresidents = Array(presidents.reversed())
print(reversedPresidents)

输出:
["Bush", "Obama", "Trump", "Biden"]
["Biden", "Trump", "Obama", "Bush"]

map函数

遍历数组中的元素,传入到后面的闭包里面,闭包的返回值组成新的数组,最后返回这个新数组。

var arr = [1, 2, 3, 4]
// [2, 4, 6, 8]
var arr2 = arr.map { $0 * 2 }

func double(_ i: Int) -> Int { i * 4 }
// [4, 8, 12, 16]
var arr3 = arr.map(double)

可以直接在闭包内添加操作逻辑,也可以直接传入一个函数

flatMap函数

若是一维数组,用法和map基本类似

但若是二维数组,就大不相同。

var arr = [[6,3,1,9], [2, 3, 4]]
// [[12, 6, 2, 18], [4, 6, 8]]
var arr2 = arr.map { $0.map{ $0*2 } }
print(arr2)
// [12, 6, 2, 18, 4, 6, 8]
var arrflat2 = arr.flatMap { $0.map{ $0*2 } }
print(arrflat2)

compactMap函数

compactMap会将数组中的元素解包,如果是nil就清除这个元素,最后返回新数组。

let possibleNumbers = ["1", "2", "three", "///4///", "5"]
// [Optional(1), Optional(2), nil, nil, Optional(5)]
let mapped: [Int?] = possibleNumbers.map { Int($0)  }
print(mapped)

// [1, 2, 5]
let compactMapped: [Int] = possibleNumbers.compactMap { Int($0)  }
print(compactMapped)

Filter函数

遍历数组中的元素,元素根据闭包内的条件过滤

var arr = [1, 2, 3, 4]
// 过滤后为 [2, 4]
var arr2 = arr.filter { $0 % 2 == 0 }
print(arr2)

let cast = ["Vivien", "Marlon", "Kim", "Karl"]
// 过滤后为 ["Kim", "Karl"]
let shortNames = cast.filter { $0.count < 5 }
print(shortNames)

reduce函数

用于遍历集合类型对象来进行求值,或构造一个新集合类型对象等。

对数组求和
let sizes = [1,2,3,4,5,6,7]
let totalSum = sizes.reduce(0, {$0 + $1})
// 28
print(totalSum)

备注:
//  单纯的累加/乘操作还可以如下实现
let totalSum = sizes.reduce(0, +)
求数组最值
llet nums = [12, 56, -9, 100, 34]
// 求最小值
let minNum = nums.reduce(Int.max) {num1 , num2 in
    return min(num1, num2)
}
// -9
print(minNum)

// 求最大值
let maxNum = nums.reduce(Int.min) {num1 , num2 in
    return max(num1, num2)
}
// 100
print(maxNum)
构建新集合类型对象
let models = [HFModel(name: "one" ,testAge: 10), HFModel(name: "two" ,testAge: 30), HFModel(name: "three" ,testAge: 90)]

print(models)
let infoMap = models.reduce(into: [String: Int]()) {result,model in
    result[model.name] = model.testAge
}
// ["two": 30, "one": 10, "three": 90]
print(infoMap)

字典

简单创建

let employee2 = [
    "name": "Taylor Swift",
    "job": "Singer", 
    "location": "Nashville"
]

或
var heights = [String: Int]()
heights["Yao Ming"] = 229
heights["Shaquille O'Neal"] = 216
heights["LeBron James"] = 206

或
var archEnemies = [String: String]()
archEnemies["Batman"] = "The Joker"
archEnemies["Superman"] = "Lex Luthor"

高阶函数调用和参考上述数组中的描述

集合

简单创建

let people = Set(["Denzel Washington", "Tom Cruise", "Nicolas Cage", "Samuel L Jackson"])

或
var people = Set<String>()
people.insert("Denzel Washington")
people.insert("Tom Cruise")
people.insert("Nicolas Cage")
people.insert("Samuel L Jackson")

部分函数使用

1 使用intersection(_:)方法,根据两个集合中都包含的值创建的一个新的集合。

2 使用symmetricDifference(_:)方法,根据在一个集合中但不在两个集合中的值创建一个新的集合。

3 使用union(_:)方法,根据两个集合的值创建一个新的集合。

4 使用subtracting(_:)方法,根据不在该集合中的值创建一个新的集合。

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

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

// []
oddDigits.intersection(evenDigits).sorted()

// [1, 9]
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()

// [1, 2, 9]
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()

1 使用“是否相等”运算符(==)来判断两个集合是否包含全部相同的值。

2 使用isSubset(of:)方法来判断一个集合中的值是否也被包含在另外一个集合中。

3 使用isSuperset(of:)方法来判断一个集合中包含另一个集合中所有的值。

4 使用isStrictSubset(of:)或者isStrictSuperset(of:)方法来判断一个集合是否是另外一个集合的子集合或者。父集合并且两个集合并不相等。

5 使用isDisjoint(with:)方法来判断两个集合是否不含有相同的值(是否没有交集)。

let a: Set = ["1","2","3","4","5","6"]
let b: Set = ["1","2"]
let c: Set = ["7"]
 
b.isSubset(of: a)  // true
a.isSuperset(of: b) // true
a.isDisjoint(with: c) // true

Set用于无序的唯一对象,Array是有序的并且可以包含重复数据
Array迭代速度比Set快,Set搜索速度比Array快

更多高阶函数调用和参考上述数组中的描述

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

推荐阅读更多精彩内容