Swift 基本语法06-数组和字典

字数 1007阅读 1673
一个iOS开发初级菜鸡.png

Swift 基本语法01-Swift简介
Swift 基本语法02-"let"和"var"
Swift 基本语法03-"if let"和"guard let"
Swift 基本语法04-"switch"和"for"
Swift 基本语法05-"String"

一、数组的定义

1.1 SwiftOC一样,使用[]定义数组,

区别:
1> Swift没有@符号
2> 中文也可以正常输出
3> 而且可以根据数组中的内容自动推导出数组的类型(和OC中的数组指定泛型类似)
Swift的写法:

let array = ["张三", "李四", "王五"]
print(array)            // 输出:["张三", "李四", "王五"]

OC的写法:

NSArray *array = @[@"张三", @"李四", @"王五"];
NSLog(@"%@", array);// 输出:见下面
/**
 * (
 * "\U5f20\U4e09",
 * "\U674e\U56db",
 * "\U738b\U4e94"
 * )
 */
1.2 Swift中基本数据类型不需要包装
let array = [1, 2, 3, 4, 5]
print(array)            // 输出:[1, 2, 3, 4, 5] 
1.3 数组中类型不一致的时候(情况比较少见)
// 会有红色的错误,并提示我们改正:Heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional
// let array3 = ["张三", 1]
let array3 = ["张三", 1] as [Any]     // 改正后的
print(array3)                        // 输出:["张三", 1]
1.4 数组的遍历

1> 按下标遍历

let array = ["张三", "李四", "王五"]

for i in 0..<array.count {
    print(array[i])
}
/**
 * 输出:
    张三
    李四
    王五
 */

2> for in遍历元素

let array = ["张三", "李四", "王五"]

for s in array {
    print(s)
}
/**
 * 输出:
    张三
    李四
    王五
 */

3> enumerated遍历,同时遍历下标和内容

let array = ["张三", "李四", "王五"]

for e in array.enumerated() {
    print(e)
    print("\(e.offset) \(e.element)")
}
/**
 * 输出:
     (offset: 0, element: "张三")
     0 张三
     (offset: 1, element: "李四")
     1 李四
     (offset: 2, element: "王五")
     2 王五
 */

4> 遍历下标和内容

let array = ["张三", "李四", "王五"]

for (n, s) in array.enumerated() {

    print("\(n) \(s)")
}
/**
 * 输出:
     0 张三
     1 李四
     2 王五
 */

5> 反序遍历

let array = ["张三", "李四", "王五"]

    for s in array.reversed() {
        print(s)
    }
/**
 * 输出:
     王五
     李四
     张三
 */

6> 反序索引和内容(先枚举,再反序)

let array = ["张三", "李四", "王五"]

    for (n, s) in array.enumerated().reversed() {
        print("\(n) \(s)")
    }
/**
 * 输出:
     2 王五
     1 李四
     0 张三
 */
1.5 数组中增加元素

1> 直接向数组中添加元素(默认添加到最后一位)

var array = ["张三", "李四", "王五"]

// 向数组中添加元素
array.append("赵六")
print(array)    // 输出:["张三", "李四", "王五", "赵六"]

2> 向数组中指定索引位置插入元素

/**
 * 向数组中指定索引位置插入元素
 * 注意:索引(at)不能超过(远数组数量 + 1)
 */
array.insert("赵六", at: 2)
print(array)    // 输出:["张三", "李四", "赵六", "王五"]
1.6 数组中删除元素

1> 通过下标删除指定的元素

var array = ["张三", "李四", "王五"]

// 通过下标删除数组中的元素
array.remove(at: 1)
print(array)    // 输出:["张三", "王五"]

2> 删除数组中的全部元素

var array = ["张三", "李四", "王五"]

// 通过下标删除数组中的元素
array.removeAll()
print(array)    // 输出:[]

3> 删除数组中的全部元素,并且保留数组的空间

var array = ["张三", "李四", "王五"]

// 通过下标删除数组中的元素
array.removeAll(keepingCapacity: true)
print("\(array) \(array.capacity)")    // 输出:[] 3

*Extension:
随着数组元素的增加,查看数组容量的变化。
可以看出:
最初数组容量为零,随着数组中元素的增加,数组的容量是成倍的增加(如果容量不够了,那就在前一个容量的基础上增大一倍)

  • var array = Int
    print("初始容量 (array.capacity)")

    for i in 0...8 {
    array.append(i)
    print("(array) 容量(array.capacity)")
    }
    /**
    初始容量 0
    [0] 容量2
    [0, 1] 容量2
    [0, 1, 2] 容量4
    [0, 1, 2, 3] 容量4
    [0, 1, 2, 3, 4] 容量8
    [0, 1, 2, 3, 4, 5] 容量8
    [0, 1, 2, 3, 4, 5, 6] 容量8
    [0, 1, 2, 3, 4, 5, 6, 7] 容量8
    [0, 1, 2, 3, 4, 5, 6, 7, 8] 容量16
    */

总结:

如果数组初始化时指定容量,可以避免插入数据时,重复分配空间,效率会高一点点。

1.7 数组中修改元素
var array = ["张三", "李四", "王五"]

// 通过下标修改数组中的元素
array[0] = "王红庆"
print(array)    // 输出:["王红庆", "李四", "王五"]
1.8 数组的合并
var array = ["张三", "李四", "王五"]
    
let array2 = ["王红庆", "18", "sui"]
array += array2
print(array)    // 输出:["张三", "李四", "王五", "王红庆", "18", "sui"]

注意:
不同类型的数组,不能直接进行合并。

var array = ["张三", "李四", "王五"] as [Any]
// 如果不加(as [Any])会报错误: Heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional
// let array2 = ["王红庆", "18", "sui", 175]
  let array2 = ["王红庆", "18", "sui", 175] as [Any]

array += array2
print(array)    // 输出:["张三", "李四", "王五", "王红庆", "18", "sui", 175]

二、字典

2.1 字典的定义

1> 普通的字典

// 如果字典中'value'的类型不同,则需要指定字典的类型为[String : Any]
let dict: [String : Any] = ["name":"王红庆", "age":18]
print(dict)     // 输出:["name": "王红庆", "age": 18]

2> 字典的数组

/**
 * 数组的类型[[String : Any]]不指定也可以
 * 但是为了明确其中的类型,还是指定一下比较直观
 */
let array: [[String : Any]] = [
    ["name":"王红庆", "age":18],
    ["name":"王白庆", "age":180]
]
print(array)    // 输出:[["name": "王红庆", "age": 18], ["name": "王白庆", "age": 180]]

*Extension:
以上形式(字典的数组)的格式最常见,一般网络传输数据都是此种类型。

  • An object that may be converted to JSON must have the following properties:
    所有对象能够被转成JSon必须遵守以下规则:
    • Top level object is an NSArray or NSDictionary
      -顶级节点必须是数组或者字典
    • All objects are NSString, NSNumber, NSArray, NSDictionary, or NSNull
      -所有的对象必须是NSString, NSNumber, or NSNull
      -NSArray, NSDictionary可以嵌套使用
    • All dictionary keys are NSStrings
      -所有的 KEY 都是 NSStrings
    • NSNumbers are not NaN or infinity
      -NSNumber不能为 nil 或者 无穷大
2.2 字典中添加元素
var dict: [String : Any] = ["name":"王红庆", "age":18]
dict["title"] = "iOS开发菜鸡"
print(dict)     // 输出:["name": "王红庆", "age": 18, "title": "iOS开发菜鸡"]
2.3 字典中删除元素
var dict = ["name":"王红庆", "age":"18"]
dict.removeValue(forKey: "name")
print(dict)     // 输出:["age": "18"]
2.4 字典中修改元素

1> 字典中,是通过KEY取值的,KEY在字典中必须是唯一的!
2> 如果KEY存在,就是新增,如果KEY不存在,就是修改

var dict = ["name":"王红庆", "age":"18"]
dict["name"] = "王白庆"
print(dict)     // 输出:["name": "王白庆", "age": "18"]

*Extension:
字典是通过KEY来定值的的,KEY必须是Hashable(可哈希的)
Hash就是将字符串变成唯一的整数,便于查找,提高字典遍历的速度

2.5 字典的遍历

1> 直接遍历

let dict: [String : Any] = ["name":"王红庆", "age":18, "title":"老司机"]
for e in dict {
    print(e)
}
/**
 (key: "name", value: "王红庆")
 (key: "age", value: 18)
 (key: "title", value: "老司机")
 */

2> 直接遍历,输出键值

let dict: [String : Any] = ["name":"王红庆", "age":18, "title":"老司机"]
for e in dict {
    print("\(e.key) \(e.value)")
}
/**
 name 王红庆
 age 18
 title 老司机
 */

3> 键值遍历
对比OC:
OC只能取到KEY,然后再根据KEYValue。而Swift可以直接取KEYValue

let dict: [String : Any] = ["name":"王红庆", "age":18, "title":"老司机"]
for (key, value) in dict {
    print("\(key) \(value)")
}
/**
 name 王红庆
 age 18
 title 老司机
 */
2.6 字典的合并
var dict1: [String : Any] = ["name":"王红庆", "age":18, "title":"老司机"]
let dict2: [String : Any] = ["name": "王白庆", "height": 190]

for e in dict2 {
    dict1[e.key] = dict2[e.key]
}
print(dict1) // 输出:["name": "王白庆", "age": 18, "title": "老司机", "height": 190]

*Tips:
1> 遍历dict2依次设置
2> 如果key存在,修改dict1的对应value
3> 如果key不存在,新增这个key和这个value

推荐阅读更多精彩内容