美文网首页Swift5.1语法学习
四、集合类型(字典、合集、数组)

四、集合类型(字典、合集、数组)

作者: 爱玩游戏的iOS菜鸟 | 来源:发表于2020-01-03 16:42 被阅读0次

    集合类型

    数组是有序值的集合。合集是唯一值的无序集合。字典是无序的键值对集合

    • 数组、合集和字典总是明确能储存的值的类型以及它们能储存的键。

    • 不可以插入一个错误类型的值到集合中,可以从集合当中取回确定类型的值

    • 创建一个集合赋值给变量即可变集合,赋值给常量即不可变集合


      集合类型

    数组(Array类型桥接到NSArray类)

    数组类型写法(完整、简写写法※)
    //Array<String> 完整写法
    var valueArr :Array<String> = Array<String>()
    //[String] 简写写法 *常用
    var valueArr1 :[String] = []
    
    数组初始化

    数组初始化方法

    var someValues :[Int] = []
    var someInts = [Int]()
    var someItems = Array.init(repeating: 123, count: 3)
    var arr2 = [String].init(repeating: "345", count: 5)
    var threeItems = Array(repeating: "Garen", count: 3)
    var threeNumArrs = Array(repeatElement([123,345], count: 3))
    var strArr :[String] = ["Garen","Ashe"]
    
    var mutiArr :[Any] = [123,"234",123.345]//Any类型 可以存放多个类型的值 但不推荐
    
    var addArr = threeItems + strArr //通过+连接符创建
    

    使用数组字面量创建 可省略变量类型
    如果已声明变量类型,只能与变量声明类型一致
    数组为[Any],可存放多种数据类型
    通过+连接符创建 【注意】数据类型兼容才可以相加

    访问数组
    1. 数组的count属性
    var strArr :[String] = ["Garen","Ashe"]
    
    print("\(strArr.count)")//数组的元素数量
    
    if strArr.isEmpty { //使用Bool类型
        print("strArr is empty")
    }
    
    1. 数组索引、下标
    var strArr :[String] = ["Garen","Ashe"]
    
    var firstObject = strArr[1]//通过下标取值
    print(strArr[strArr.index(after: strArr.startIndex)])
    print(strArr[strArr.index(before: strArr.endIndex)])
    
    print(strArr[strArr.index(strArr.count, offsetBy: -1)])
    
    var index: Int? = strArr.firstIndex(of: "Ashe")//可能没有值 为可选类型
    print(strArr[strArr.index(index!, offsetBy: -1)])
    
    1. 数组元素替换
    var strArr :[String] = ["Garen","Ashe"]
    
    var firstObject = strArr[0]//通过下标取值
    strArr[0] = "Ionia"//直接改变下标所在值
    print(firstObject)//z索引对应的值改变 不改变firstObject的值
    
    strArr[0..<2] = ["Ashe","Catallina","Parker"]//可以替换范围长度不同的值的合集 但是前面的范围不允许越界
    
    1. 数组元素插入
    //数组元素插入
    
    strArr.insert("Nocxus", at: 2)
    strArr.insert("Hello", at: strArr.endIndex)
    strArr.insert("World", at: strArr.index(after: strArr.startIndex))
    strArr.insert(contentsOf: ["Who"], at: strArr.endIndex)
    
    print(strArr)//输出:["Ashe", "World", "Catallina", "Nocxus", "Parker", "Hello", "Who"]
    
    var index1 :Int? = strArr.firstIndex(of: "World")
    var index2 :Int? = strArr.index(before: strArr.endIndex)
    
    if let min = index1, let max = index2 {
        let replaceRange = min...max
        strArr.replaceSubrange(replaceRange, with: ["Year","Month","Day"])
        print(strArr)//输出:["Ashe", "Year", "Month", "Day"]
    }
    
    1. 数组元素删除
    var strArr :[String] = ["Garen","Ashe","Nocxus","Demacia","Hello","Year"]
    
    let deleteFirstItem = strArr.remove(at: 0)//删除该并返回该元素的值
    strArr.removeFirst();//删除首位元素
    
    let deleteLastItem = strArr.removeLast()//删除末尾元素
    
    print(deleteFirstItem,deleteLastItem,strArr)//输出: Garen Demacia ["Nocxus", "Demacia", "Hello"]
    
    strArr.removeAll()//删除所有元素
    
    1. 数组元素遍历
    //通过for-in遍历数组
    for item in strArr {
        print(item)
    }
    
    for (index,item) in strArr.enumerated() {
        print(index,item)
    }
    
    1. 数组元素操作
    var arr = [1, 2, 3, 4]
    var arrS = ["1", "2", "3", "4"]
    //映射用map
    var arr2 = arr.map { $0 * 2 }//返回数组
    var arrS = arr.map { "abc_\($0)" }
    //map也可以接受一个同类型的表达式 达到同样的效果
    func double(_ element:Int) -> Int{
        element * 2
    }
    print(arr.map(double))
    
    //遍历元素 并将循环产生的结果放到数组中
    //[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4]]
    var arr2 = arr.map { Array.init(repeating: $0, count: $0) }
    //遍历元素 并将循环产生的数组中的元素g合并到一个数组中
    //[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
    var arr3 = arr.flatMap { Array.init(repeating: $0, count: $0)}
    
    var arr = ["123", "123", "jack", "-30"]
    //[Optional(123), Optional(123), nil, Optional(-30)]
    var arr2 = arr.map { Int($0) }
    //压缩紧凑
    //[123, 123, -30]
    var arr3 = arr.compactMap { Int($0) }
    
    //过滤 用filter
    var arr3 = arr.filter {  $0 > 2 }//返回数组
    
    //当前后遍历有关联用reduce
    //元素总和
    var result = arr.reduce(0) { $0 + $1}//$0 上一次遍历相加结果 $1数组元素
    var result2 = arr.reduce(0, +)//更精简
    
    //使用reduce 实现map函数的功能
    var arr = [1, 2, 3, 4]
    //数组相加 合并为新的数组
    var arr2 = arr.reduce([]) { $0 + [$1 * 2] }
    
    //使用reduce 实现filllter函数的功能
    var arr3 = arr.reduce([]) { $1 % 2 == 0 ? $0 + [$1] : $0 }
    

    lazy属性可以对map进行优化

    let arr = [1,2,3]
    
    let result = arr.lazy.map { (value) -> Int in
        print("mapping \(value)")
        return value * 2
    }
    
    print("begin---")
    print("result count",result.count)//count不会影响lazy属性
    print("mapped",result[0])
    print("mapped",result[1])//使用一次遍历一次
    print("mapped",result[2])
    print("end---")
    
    /*
     输出结果:
     begin---
     result count 3
     mapping 1
     mapped 2
     mapping 2
     mapped 4
     mapping 3
     mapped 6
     end---
     **/
    
    let result2 = arr.map { (value) -> Int in
        print("mapping \(value)")
        return value * 2
    }
    
    print("begin---")
    print("mapped",result2[0])
    print("mapped",result2[1])
    print("mapped",result2[2])
    print("end---")
    /* 输出结果:
    mapping 1
    mapping 2
    mapping 3
    begin---
    mapped 2
    mapped 4
    mapped 6
    end---
    */
    

    集合(Set类型桥接到基础类NSSet类)

    集合的属性
    • 合集将同一类型且不重复的值无序地储存在一个集合当中。
    • Set类型的哈希值:类型必须提供计算自身哈希值的方法,哈希值是Int值且所有的对比起来相等的对象都相同,比如a==b a.hashValue = b.hashValue
    • Swift的所有基础类型都是可哈希的,并且可以用于集合或者字典的键 没有关联值的枚举成员值,同样默认可哈希
    集合类型语法

    Set<Element> 没有简写

    集合初始化
    1. 使用初始化器语法创建确定类型的空集合
    var letters = Set<Character>()
    letters.insert("a")
    letters = []//基于初始化器的类型,被推断为Set<Character
    
    1. 使用数组字面量创建集合
    var letters = Set<Character>()
    letters.insert("a")
    letters = []//基于初始化器的类型,被推断为Set<Character
    
    var favoriteHeors :Set<String> = ["Jiawen IV","Paker","Trondel","Trondel"]//String值的集合 重复元素会被删除
    
    //集合类型不能从字面量推断 所以必须显示声明
    //但是在使用相同类型的数组字面量不用写集合的包含类型
    var demaciaHeros :Set = ["Lax","Silas","Shavans","Gallio"]//根据【类型推断】,集合类型为<String>
    
    集合的访问及修改
    1. 集合count属性 isEmpty属性 contains()函数
    if !demaciaHeros.isEmpty {
        print("demaciaHeros have \(demaciaHeros.count) items")//输出:demaciaHeros have 4 items
    }
    
    if !demaciaHeros.contains("Vain") {
        print("demaciaHeros haven't Vain")//输出:demaciaHeros haven't Vain
    }
    
    1. 添加元素
    demaciaHeros.insert("Vain")//返回插入是否成功Bool 以及插入值
    
    1. 删除元素
    demaciaHeros.removeFirst()//删除首个元素
    demaciaHeros.remove("Vain")//删除指定元素
    
    1. 删除元素
    for hero in demaciaHeros {
        print(hero)//输出:Silas Shavans Gallio
    }
    
    //以特定的顺序遍历 把合集的元素用sorted()方法作为使用(<)运算符排序的数组返回
    for hero in demaciaHeros.sorted(by: <) {
        print(hero)//输出:Gallio Shavans Silas
    }
    
    集合相关基本操作
    1. 两集合操作产生New合集
    • 使用 intersection(_:)方法来创建一个只包含两个合集共有值的新合集
    • 使用 symmetricDifference(_:)方法来创建一个只包含两个合集各自有的非共有值的新合集
    • 使用 union(_:)方法来创建一个包含两个合集所有值的新合集
    • 使用 subtracting(_:)方法来创建一个两个合集当中不包含某个合集值的新合集
      阴影部分表示两个集合操作结果
    var oneDigist :Set<Int> = [1, 2, 3, 4, 5]
    var twoDigist :Set<Int> = [1, 2, 6, 7, 8]
    
    print(oneDigist.union(twoDigist).sorted(by: >))// a U b
    print(oneDigist.intersection(twoDigist).sorted(by: >))// a Π b
    print(oneDigist.subtracting(twoDigist))
    print(oneDigist.symmetricDifference(twoDigist))
    
    1. 两集合成员关系和相等性
    • 使用“相等”运算符 (==)来判断两个合集是否包含有相同的值;
    • 使用 isSubset(of:)方法来确定一个合集的所有值是被某合集包含;
    • 使用 isSuperset(of:)方法来确定一个合集是否包含某个合集的所有值;
    • 使用 isStrictSubset(of:)或者isStrictSuperset(of:)方法来确定是个合集是否为某一个合集的子集或者超集,但并不相等;
    • 使用 isDisjoint(with:)方法来判断两个合集是否拥有完全不同的值。
      集合成员关系和相等性图解
    var oneDigist :Set<Int> = [1, 2, 3, 4, 5]
    var twoDigist :Set<Int> = [1, 2, 4, 5, 3]
    
    let threeDigist :Set<Int> = [1, 2, 3]
    
    print(oneDigist == twoDigist)//输出:false
    print(threeDigist.isSubset(of: oneDigist))//输出:true
    print(oneDigist.isSuperset(of: threeDigist))//输出:true
    
    print(twoDigist.isStrictSubset(of: oneDigist))//输出:false
    print(oneDigist.isStrictSuperset(of: twoDigist))//输出:false
    
    print(oneDigist.isDisjoint(with: twoDigist))//输出:false
    

    字典(Dictionary类型桥接到基础类NSDictionary类)

    • 字典储存无序的互相关联的同一类型的键和同一类型的值的集合
    字典类型写法

    Dictionary<Key,Value> 简写[Key,Value]

    字典初始化
    var nameDic :Dictionary <String,String> = [:]
    var name2Dic = [String:String]()
    
    //用字典字面量创建字典
    var numRomanDic :Dictionary<String,String> = ["1":"one","2":"two"]//完整写法
    var numRoman2Dic :[String:String] = ["1":"one","2":"two"]//简写方式 *推荐
    
    //根据字面量创建 省略声明类型声明以及键值类型
    
    字典访问及修改
    1. count属性 isEmpty属性
    if !numRomanDic.isEmpty {
        print(numRomanDic.count)
    }
    
    1. 添加、更改key关联的值
    numRomanDic["4"] = "four"//使用下标h给字典添加元素
    numRomanDic["1"] = "five"//更改key关联的值
    
    //通过updateValue(<value:>, forKey:)设置或更改值
    numRomanDic.updateValue("six", forKey: "6")//返回nil即为添加
    numRomanDic.updateValue("one", forKey: "1")//返回旧值即为修改
    

    与下标不同点在于updateValue(<value:>, forKey:)在执行更新之后返回旧的值,可允许你检查更新是否成功,返回的值是一个字典值类型的可选值 可能为nil(即添加该键值)

    返回的值是一个字典值类型的可选值
    1. 通过键取值也是可选类型
    //通过可选定绑定类判断
    if let num = numRomanDic["1"] {
        print(num)
    }
    
    1. 删除键值对(同理也有直接赋值nil 或通过removeValue(forKey:)方法通过返回的可选值来判断是否成功)
    numRomanDic["1"] = nil//使用下标脚本语法删除键值对
    
    if let isDelete = numRomanDic.removeValue(forKey: "2") {
        print(isDelete)
    }
    
    1. 遍历字典
    for (key, value) in numRomanDic {
        print(key,value)
    }
    
    for key in numRomanDic.keys {
        print(key)
    }
    
    for value in numRomanDic.values {
        print(value)
    }
    
    let numRomanKeys = [String](numRomanDic.keys)
    let numRomanValues = [String](numRomanDic.values)
    

    Swift学习日记4.0

    相关文章

      网友评论

        本文标题:四、集合类型(字典、合集、数组)

        本文链接:https://www.haomeiwen.com/subject/kxczoctx.html