[关闭]
@phper 2016-09-03T05:39:14.000000Z 字数 7289 阅读 4357

swift 5. 数组

swift


妈蛋,真不容易啊,终于要说集合了。哎╮(╯▽╰)╭。这进度太慢了啊!

swift中的集合分好几种,他们统统成为集合类型。还是PHP大发好啊,一个数组类型就搞定所有。

按照可以是否存在相同类型的数据,具体分为,以下:

数组 Arrays

swift中的数组跟java和c 一样,只能包含相同类型的成员数据,要么全是整型,要么全是字符串,不能几种不同的类型混在一块,要是你想混在一起就得用object-c语言里面的的NSArray类型,最后会说到。

0. 申明一个数组

如何申明一个数组呢,和javascript是一样的,用[]表示。但是,我们要申明这个数组是要有变量类型的。所以,要用[类型]来标记。

  1. //先申明
  2. var array1:[String]
  3. //后赋值
  4. array1 = ["ab","cb","ed"]
  5. print(array1) // 打印:[ab, cb, ed]

或者是申明和赋值连着一起来:

  1. //申明赋值一起来
  2. var array2:[Int] = [1,2,3,4,5,6]
  3. print(array2)

上面2种方法都是先申明,后赋值了。swift中还有一种申明数组的方式,是申明一个空数组,或者叫先申明一个数组,给它附上空值。因为一个数组光申明,如果不初始化赋值,打印它是会报错。

  1. var array6 = [Int]() //申明Int类型数组并初始化赋值为空
  2. var array8 = [String]() //申明String类型数组并初始化赋值为空
  3. print(array6)

我们也可以在申明一个数组后,给它设定默认的值:
var array = [type](count: count, repeatedValue:"value")
type 表示填充的变量类型。count 表示数组大小,repeatedValue 表示填充的值是什么。

  1. var threeString = [String](count: 3, repeatedValue:"hello")
  2. var threeInt= [Int](count: 3, repeatedValue:8)
  3. print(threeString) // [hello, hello, hello]
  4. print(threeInt) // [8, 8, 8]

或者直接去掉变量类型,swift会自动判断的:
var array = Array(count: count, repeatedValue:"value")

  1. var threeString = Array(count: 3, repeatedValue:"hello")
  2. print(threeString) // [hello, hello, hello]

之前我们就说过,swift中的变量的类型,我们是可以省略的,就像javascript的写法一样所以,swift会自动识别它的类型,所以一般我们会这样来表示一个数组:

  1. var array3 = [1,2,3,4,5]
  2. var array4 = ["a","b","c","d"]
  3. var array5 = ["0",1,"ere"]
  4. //输出
  5. print(array3)
  6. print(array4)
  7. print(array5)
  8. //屏幕输出结果
  9. [1, 2, 3, 4, 5]
  10. [a, b, c, d]
  11. [1, 2, 3, "2111"]

注意
我们看到array5中居然是不同的数据类型成员,但是,编辑器没报错?你不是说swift中的数组是严格要求类型的吗?会报错吗?怎么这个是好的,还输出了。

因为,我们采用的是省略的写法,它就自动识别成[NSObject]类型了。所以也是正确的。最好不要用这种用法。

其他语言中是怎么申明和赋值数组的呢?

先是java, 哎,Java的一切都是蛋疼的,因为它推崇一切都是对象,所以,数组也是对象,也要new 初始化。

  1. /*
  2. java
  3. */
  4. //1 先申明,再new
  5. String array1[];
  6. array1 = new String[3];
  7. //只能一个一个赋值
  8. array1[0]= "ww";
  9. array1[1]= "ww";
  10. array1[2]= "ww";
  11. //array1[3]= "ww"; //因为只申明了3个值,这个就溢出了,报错。蛋疼!
  12. // 2. 一起
  13. String array2[] = new String[3];
  14. //只能一个一个赋值
  15. array2[0]= "ww";
  16. array2[1]= "ww";
  17. array2[2]= "ww";
  18. //第二种方式, 一步到位,并赋值
  19. String array3[] = {"ww","fg","ere"};
  20. //这个时候只能修改原来的值了,不能新增值,因为只有3个
  21. array3[0] = 123; // 不匹配,报错,只能是字符串
  22. array3[3] = "erd"; // 溢出了,报错!
  23. for (String i:array3) {
  24. System.out.println(i);
  25. }

php中当然是最爽的啦。随意使用!真是太爽了。

  1. $a = []; //当然这一句也可以不要, 也不会错
  2. $a = [
  3. 1,2,3,"wohahah",5,"xixii"
  4. ];
  5. $a[55] = "566";

javascript中,和swift很像

  1. var array1[]; //申明一下。
  2. array1= [1,2,3,4,5];//赋值
  3. array1[0] = 9; //修改

1. 求数组大小

swift中也是用count来求数组大小,但是它是个数组的一个属性值,不是一个函数方法。

  1. var array8 = [1,2,3,4,5,6,7,8,9];
  2. var array_8_count = array8.count;
  3. print("array8数组的大小为:\(array_8_count)")
  4. //输出: array8数组的大小为:9

2. 判断数组是否为空

用属性isEmpty 来判断,它返回一个boolean值,true或false

  1. if array8.isEmpty {
  2. print("The array8 is empty.")
  3. } else {
  4. print("The array8 is not empty.")
  5. }

3. 访问和修改数组成员

上面我们申明了很多数组,我们想要访问里面的某一个成员,比如访问第N个的值,我们可以和其他语言一样,用array[N]来访问的。

  1. var shoppingList = ["Eggs", "Milk"]
  2. var index_0 = shoppingList[0];
  3. var index_1 = shoppingList[1];
  4. print(index_0); //输出Eggs
  5. print(index_1); //输出Milk

既然我们可以通过array[0]这样的方式取到第0个值,我们也同样可以用array[0] = "Pig"这样的方式,给第0个成员重新赋值,因为这个数组申明的为var变量,是可以重新修改赋值的,注意 如果是申明为let常量就不能这样改动了

  1. var shoppingList = ["Eggs", "Milk"]
  2. shoppingList[0] = "Pig" //将第0个元素重新赋值位Pig
  3. shoppingList[1] = "Dog" //将第1个元素重新赋值位Dog
  4. var index_0 = shoppingList[0];
  5. var index_1 = shoppingList[1];
  6. print(index_0); //Pig
  7. print(index_1); //Dog

注意
下面会出现一个问题,也是极其容易想当然出错的。上面我们申明shoppList数组长度为2,那么它就限定死了。它的长度为2了。如果你通过array[2] = "hello"这种方式给它加上第3个成员,是会报错fatal error: Array index out of range

  1. var shoppingList = ["Eggs", "Milk"]
  2. shoppingList[2] = "Hello" //报错:fatal error: Array index out of range

那,难道我们就不能给一个预先定义的数组扩充吗?当然可以。看下面:

使用区间来修改数组

  1. var oneToFive = [1,2,3,4,5]
  2. oneToFive[0...2] = [6,7,8] // 0-2的索引值变成6.7.8
  3. print(oneToFive) // [6,7,8,4,5]
  4. oneToFive[0..<3] = [9] // 把 0-2的全变成9
  5. print(oneToFive) // [9, 4, 5]

4. 向数组后追加新的成员

上面我们看到了,强行给数组添加新的成员是会报错的,那如何向数组后面追加新的成员呢?swift里也有这样一个方法函数append(),它是一个数组对象的一个方法,可以向这个数组后添加成员。

  1. var animals = ["pig", "dog", "cat"]
  2. animals.append("monkey")
  3. print(animals) //输出:[pig, dog, cat, monkey]
  4. print(animals[3]) // 输出:monkey

5. 向里数组任意某个索引值之前添加数据

append()方法是向数组的最后面追加数据,感觉比较鸡肋,不灵活,swift中的一个方法insert("value", atIndex: index)就非常灵活了。可以往任意索引前追加数据,记住,是往前。注意 : 后面的atIndex一定要写,不能省略。

  1. var foods = ["egg","bread","rice"]
  2. //往第0个索引,也就是egg,前面添加icecream。
  3. foods.insert("icecream", atIndex:0)
  4. //往第一个索引,注意,这时候,egg就变成第1个数据了。
  5. foods.insert("humbeag", atIndex:1)
  6. print(foods)
  7. //打印:[icecream, humbeag, egg, bread, rice]

那么,既然有向前某个索引值钱追加,有往某个索引值后面追加的函数吗?对不起!没有。啊。你会觉得苹果很操蛋啊。其实不是。insert("value", atIndex:index)这个函数是往前追加,按照相对论的定义,不也是在往index-1的后面在追加数据吗?

  1. var foods = ["egg","bread","rice"]
  2. //我想往第1个索引值,也就是bread后面追加banana, 其实,也就是在rice,index=2前面追加了,对不对。
  3. foods.insert("banana", atIndex: 2)
  4. println(foods) //输出:[egg, bread, banana, rice]

7. 获取数组的第一个元素和最后一个元素

获取第一个元素和最后一个元素,返回的是可选型

  1. var vowels: [Int] = [1,2,3,4,5]
  2. print(vowels.first) // Optional(1)
  3. print(vowels.last) // Optional(5)
  4. //因为是可选型,所以用if let解包下
  5. if let firstVowel = vowels.first{
  6. print("The first vowel is " , firstVowel) // The first vowel is 1
  7. }
  8. //强型解包
  9. print(vowels.first!) // 1
  10. vowels[vowels.count-1] // 5

8. 最大值、最小值

获取最小,最大值,返回的也是可选型

  1. vowels.minElement() // Optional(1)
  2. vowels.maxElement() // Optional(5)

9. 获取数组区间内的值

获取使用一个区间内的值。

  1. vowels[1...2] // 从第2个-第3个的值: [2, 3]
  2. vowels[1..<2] // 从第2个-第3个的值,不包含3 : [2]
  3. vowels[1...vowels.count - 1] //取出 第 2个到最后一个的值: [2,3,4,5]

10. 数组包含

一个数组内是否包含一个值:Array.contains[n]。返回truefalse

  1. vowels.contains(1) // true
  2. vowels.contains(33) // false
  3. let letter = 2
  4. if vowels.contains( letter ){
  5. print("\(letter) is a vowel") // 输出这句
  6. }
  7. else{
  8. print("\(letter) is not a vowel")
  9. }

查看一个元素在一个数组中的索引位置:Array.indexOf[n]。 返回的是可选类型。

  1. var vv1 = vowels.indexOf(1) //1这个元素在0的索引上。
  2. print(vv1) // Optional(0)
  3. var vv2 = vowels.indexOf(8) //没有8这个元素,返回nil
  4. print(vv2) // nil

11. 合并数组

可以用+=操作符号,来扩充数组,或者合并几个数组。arrray1+=["value1","value2"] ,必须是相同类型的数据。

  1. var mobile = ["iphone","htc","moto"]
  2. mobile+=["huawei","lenove",]
  3. mobile+=[4565] //类型不相同,报错。
  4. var mobile2 = ["nokia"]
  5. mobile += mobile2
  6. //拆开也可以
  7. var mobile3 = mobile + mobile2
  8. print(mobile3)
  9. // 输出:[iphone, htc, moto, huawei, lenove, 'nokia']

12. 删除某个索引值的数据

删除某个索引的值,可以用removeAtIndex(index)来移除,返回值是移除的这一项的值。

  1. var mobile3 = ["iphone","htc","moto", "nokia"]
  2. var who = mobile3.removeAtIndex(3)
  3. print(who) // 打印:nokia
  4. print(mobile3) // 打印:[iphone, htc, moto] nokia被移除了。

删除第一项和最后一项,可以用removeFirst()removeLast(),返回的是移除的这一项的值。

  1. var mobile3: [String] = ["iphone","htc","moto", "nokia"]
  2. var who1 = mobile3.removeFirst()
  3. print(who1) // 打印:iphone
  4. var who2 = mobile3.removeLast()
  5. print(who2) // 打印:nokia
  6. print(mobile3) // 打印:["htc","moto"] iphone, nokia被移除了。

删除所有,用:removeAll() 。它返回删除的值。

  1. var mobile3: [String] = ["iphone","htc","moto", "nokia"]
  2. mobile3.removeAll()

删除一个区间:removeRange(1...3) ,没返回值。

  1. var mobile3: [String] = ["iphone","htc","moto", "nokia"]
  2. mobile3.removeRange(1..<2) //删除了 htc
  3. mobile3.removeRange(1...2) //删除了 htc 和 moto

13. 遍历数组

遍历数组,我们直接用for语句循环。以后将for会着重说:

  1. for i in shoppingList {
  2. print(i)
  3. }
  4. //输出:
  5. Pig
  6. Dog
  7. hello

或者我们想吧索引值也给循环出来,得用到枚举了。以后也会说到:

  1. for (index, value) in enumerate(shoppingList) {
  2. print("Item \(index): \(value)")
  3. }
  4. //输出
  5. Item 0: Pig
  6. Item 1: Dog
  7. Item 2: hello

14. 数组比较

swift中数组比较用==。它比较的的是值,和其它语言不一样。所以,比较2个数组,只要值是一摸一样就会相等。

  1. var oneToFive = [1,2,3,4,5]
  2. var numbers = [1,2,3,4,5]
  3. numbers == oneToFive // true
  4. //顺序变化就不想等了
  5. var oneToFive2 = [1,2,4,3,5]
  6. numbers == oneToFive2 //false

15. 二维数组

  1. //二维数组的声明
  2. var board = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]
  3. //var board:[[Int]] = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]
  4. //var board:[Array<Int>] = = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]
  5. //var board:Array<[Int]> = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]
  6. //var board:Array<Array<Int>> = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]
  7. // 二维数组获取元素
  8. board[0]
  9. board[0][0]
  10. // 获取二维数组两个维度的信息
  11. board.count
  12. board[0].count
  13. // Swift中的二维数组,每一维度的元素数目可以不同
  14. board[0].append(0)
  15. board
  16. // 为二维数组的第一个维度添加的元素是一个数组
  17. board.append([0,0,0,0])
  18. board += [ [0,0,0,0] ]
  19. board

NSArray

NSArray数组是swift的前任objective-c里的声明数组的方式,在swift也被沿用了过来。简单说下,怎么使用,用的不多了。

  1. //默认这样声明,不加类型,就是声明一个 NSArray
  2. var Narray1 = []
  3. // 用as 关键字转换
  4. var Narray2 = [1,2,3,4,5] as NSArray
  5. //显示的声明
  6. var Narray3: NSArray = [1,"hello"]
  7. var Narray4: [NSObject] = [1,"hello"]

好了。数组也说到这了。妈的。太不容易了。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注