swift 5. 数组

前端之家收集整理的这篇文章主要介绍了swift 5. 数组前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

swift 5. 数组

标签:swift


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

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

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

  • 数组 Arrays
  • 字典 Dictionaries

数组 Arrays

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

0. 申明一个数组

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

//先申明@H_301_32@
var@H_301_32@ array1:[String@H_301_32@]

//后赋值@H_301_32@
array1 = ["ab"@H_301_32@,"cb"@H_301_32@,"ed"@H_301_32@]

print(array1) // 打印:[ab,cb,ed]@H_301_32@

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

//申明赋值一起来@H_301_32@
var@H_301_32@ array2:[Int] = [1@H_301_32@,2@H_301_32@,3@H_301_32@,4@H_301_32@,5@H_301_32@,6@H_301_32@]

print@H_301_32@(array2)

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

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

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

var threeString = [String@H_301_32@](count: 3,repeatedValue:"hello"@H_301_32@)
var threeInt= [Int@H_301_32@](count: 3,repeatedValue:8@H_301_32@)

print(threeString) // [hello,hello,hello]
print(threeInt) // [8,8,8]

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

var@H_301_32@ threeString = Array@H_301_32@(count: 3@H_301_32@,repeatedValue:"hello"@H_301_32@)

print@H_301_32@(threeString) // [hello,hello]@H_301_32@

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

var@H_301_32@ array3 = [1@H_301_32@,5@H_301_32@]
var@H_301_32@ array4 = ["a"@H_301_32@,"b"@H_301_32@,"c"@H_301_32@,"d"@H_301_32@]
var@H_301_32@ array5 = ["0"@H_301_32@,1@H_301_32@,"ere"@H_301_32@]

//输出@H_301_32@
print@H_301_32@(array3)
print@H_301_32@(array4)
print@H_301_32@(array5)

//屏幕输出结果@H_301_32@
[1@H_301_32@,5@H_301_32@]
[a,b,c,d]
[1@H_301_32@,"2111"@H_301_32@]

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

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

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

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

/* java */@H_301_32@

//1 先申明,再new@H_301_32@
String array1[];
array1 = new@H_301_32@ String[3@H_301_32@];
//只能一个一个赋值@H_301_32@
array1[0@H_301_32@]= "ww"@H_301_32@;
array1[1@H_301_32@]= "ww"@H_301_32@;
array1[2@H_301_32@]= "ww"@H_301_32@;
//array1[3]= "ww"; //因为只申明了3个值,这个就溢出了,报错。蛋疼!@H_301_32@

// 2. 一起@H_301_32@
String array2[] = new@H_301_32@ String[3@H_301_32@];
//只能一个一个赋值@H_301_32@
array2[0@H_301_32@]= "ww"@H_301_32@;
array2[1@H_301_32@]= "ww"@H_301_32@;
array2[2@H_301_32@]= "ww"@H_301_32@;

//第二种方式,一步到位,并赋值@H_301_32@
String array3[] = {"ww"@H_301_32@,"fg"@H_301_32@,"ere"@H_301_32@};
//这个时候只能修改原来的值了,不能新增值,因为只有3个@H_301_32@
array3[0@H_301_32@] = 123@H_301_32@; // 不匹配,报错,只能是字符串@H_301_32@
array3[3@H_301_32@] = "erd"@H_301_32@; // 溢出了,报错!@H_301_32@


for@H_301_32@ (String i:array3) {
    System.out.println(i);
}

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

$a@H_301_32@ = []; //当然这一句也可以不要,也不会错@H_301_32@
$a@H_301_32@ = [
    1@H_301_32@,"wohahah"@H_301_32@,"xixii"@H_301_32@
];
$a@H_301_32@[55@H_301_32@] = "566"@H_301_32@;

javascript中,和swift很像

var@H_301_32@ array1[]; //申明一下。@H_301_32@
array1= [1@H_301_32@,5@H_301_32@];//赋值@H_301_32@
array1[0@H_301_32@] = 9@H_301_32@; //修改@H_301_32@

1. 求数组大小

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

var@H_301_32@ array8 = [1@H_301_32@,6@H_301_32@,7@H_301_32@,8@H_301_32@,9@H_301_32@];

var@H_301_32@ array_8_count = array8.count;

print@H_301_32@("array8数组的大小为:\(array_8_count)"@H_301_32@)
//输出: array8数组的大小为:9@H_301_32@

2. 判断数组是否为空

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

if@H_301_32@ array8.isEmpty {
    print@H_301_32@("The array8 is empty."@H_301_32@)
} else@H_301_32@ {
    print@H_301_32@("The array8 is not empty."@H_301_32@)
}

3. 访问和修改数组成员

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

var@H_301_32@ shoppingList = ["Eggs"@H_301_32@,"Milk"@H_301_32@]
var@H_301_32@ index_0 = shoppingList[0@H_301_32@];
var@H_301_32@ index_1 = shoppingList[1@H_301_32@];

print@H_301_32@(index_0); //输出Eggs@H_301_32@
print@H_301_32@(index_1); //输出Milk@H_301_32@

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

var@H_301_32@ shoppingList = ["Eggs"@H_301_32@,"Milk"@H_301_32@]

shoppingList[0@H_301_32@] = "Pig"@H_301_32@ //将第0个元素重新赋值位Pig@H_301_32@
shoppingList[1@H_301_32@] = "Dog"@H_301_32@ //将第1个元素重新赋值位Dog@H_301_32@

var@H_301_32@ index_0 = shoppingList[0@H_301_32@];
var@H_301_32@ index_1 = shoppingList[1@H_301_32@];

print@H_301_32@(index_0); //Pig@H_301_32@
print@H_301_32@(index_1); //Dog@H_301_32@

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

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

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

使用区间来修改数组

var@H_301_32@ oneToFive = [1@H_301_32@,5@H_301_32@] 

oneToFive[0.@H_301_32@..2@H_301_32@] = [6@H_301_32@,8@H_301_32@]  // 0-2的索引值变成6.7.8@H_301_32@
print@H_301_32@(oneToFive) // [6,7,4,5]@H_301_32@

oneToFive[0.@H_301_32@.<3@H_301_32@] = [9@H_301_32@] // 把 0-2的全变成9@H_301_32@
print@H_301_32@(oneToFive) // [9,5]@H_301_32@

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

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

var@H_301_32@ animals = ["pig"@H_301_32@,"dog"@H_301_32@,"cat"@H_301_32@]

animals.append@H_301_32@("monkey"@H_301_32@)

print@H_301_32@(animals) //输出:[pig,dog,cat,monkey]@H_301_32@
print@H_301_32@(animals[3@H_301_32@]) // 输出:monkey@H_301_32@

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

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

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

print@H_301_32@(foods)
//打印:[icecream,humbeag,egg,bread,rice]@H_301_32@

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

var@H_301_32@ foods = ["egg"@H_301_32@,"rice"@H_301_32@]

//我想往第1个索引值,也就是bread后面追加banana,其实,也就是在rice,index=2前面追加了,对不对。@H_301_32@
foods.insert("banana"@H_301_32@,atIndex: 2@H_301_32@)

println@H_301_32@(foods) //输出:[egg,banana,rice]@H_301_32@

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

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

var@H_301_32@ vowels: [Int] = [1@H_301_32@,5@H_301_32@]

print@H_301_32@(vowels.first) // Optional(1)@H_301_32@
print@H_301_32@(vowels.last) // Optional(5)@H_301_32@

//因为是可选型,所以用if let解包下@H_301_32@
if@H_301_32@ let firstVowel = vowels.first{
    print@H_301_32@("The first vowel is "@H_301_32@,firstVowel) // The first vowel is 1@H_301_32@
}

//强型解包@H_301_32@
print@H_301_32@(vowels.first!) // 1@H_301_32@

vowels[vowels.count-1@H_301_32@] // 5@H_301_32@

8. 最大值、最小值

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

vowels.minElement() // Optional(1)@H_301_32@
vowels.maxElement() // Optional(5)@H_301_32@

9. 获取数组区间内的值

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

vowels[1...2]@H_301_32@ // 从第2个-第3个的值: [2,3]@H_301_32@
vowels[1..<2]@H_301_32@ // 从第2个-第3个的值,不包含3 : [2]@H_301_32@

vowels[1...vowels.count - 1]@H_301_32@ //取出 第 2个到最后一个的值: [2,3,5]@H_301_32@

10. 数组包含

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

vowels.contains@H_301_32@(1@H_301_32@) // true@H_301_32@
 vowels.contains@H_301_32@(33@H_301_32@) // false@H_301_32@

let letter = 2@H_301_32@
if@H_301_32@ vowels.contains@H_301_32@( letter ){
    print("\(letter) is a vowel"@H_301_32@) // 输出这句@H_301_32@
}
else@H_301_32@{
    print("\(letter) is not a vowel"@H_301_32@)
}

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

var@H_301_32@ vv1 = vowels.indexOf(1@H_301_32@) //1这个元素在0的索引上。@H_301_32@
print@H_301_32@(vv1) // Optional(0)@H_301_32@

var@H_301_32@ vv2 = vowels.indexOf(8@H_301_32@) //没有8这个元素,返回nil@H_301_32@
print@H_301_32@(vv2) // nil@H_301_32@

11. 合并数组

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

var@H_301_32@ mobile = ["iphone"@H_301_32@,"htc"@H_301_32@,"moto"@H_301_32@]

mobile+=["huawei"@H_301_32@,"lenove"@H_301_32@,]
mobile+=[4565@H_301_32@] //类型不相同,报错。@H_301_32@

var@H_301_32@ mobile2 = ["nokia"@H_301_32@]
mobile += mobile2
//拆开也可以@H_301_32@
var@H_301_32@ mobile3 = mobile + mobile2

print@H_301_32@(mobile3)
// 输出:[iphone,htc,moto,huawei,lenove,'nokia']@H_301_32@

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

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

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

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

var@H_301_32@ mobile3: [String] = ["iphone"@H_301_32@,"nokia"@H_301_32@]
var@H_301_32@ who1 = mobile3.removeFirst()
print@H_301_32@(who1) // 打印:iphone@H_301_32@

var@H_301_32@ who2 = mobile3.removeLast()
print@H_301_32@(who2) // 打印:nokia@H_301_32@

print@H_301_32@(mobile3) // 打印:["htc","moto"] iphone,nokia被移除了。@H_301_32@

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

var@H_301_32@ mobile3: [String@H_301_32@] = ["iphone"@H_301_32@,"nokia"@H_301_32@]
mobile3.removeAll()

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

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

13. 遍历数组

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

for@H_301_32@ i in@H_301_32@ shoppingList {
    print@H_301_32@(i)
}
//输出:@H_301_32@
Pig
Dog
hello

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

for@H_301_32@ (index,value@H_301_32@) in@H_301_32@ enumerate(shoppingList) {
    print("Item \(index): \(value)"@H_301_32@)
}
//输出@H_301_32@
Item 0@H_301_32@: Pig
Item 1@H_301_32@: Dog
Item 2@H_301_32@: hello

14. 数组比较

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

var@H_301_32@ oneToFive = [1@H_301_32@,5@H_301_32@]
var@H_301_32@ numbers = [1@H_301_32@,5@H_301_32@]
numbers == oneToFive // true@H_301_32@

//顺序变化就不想等了@H_301_32@
var@H_301_32@ oneToFive2 = [1@H_301_32@,5@H_301_32@] 
numbers == oneToFive2 //false@H_301_32@

15. 二维数组

//二维数组的声明@H_301_32@
var@H_301_32@ board = [ [1024@H_301_32@,16@H_301_32@,2@H_301_32@,0@H_301_32@],[256@H_301_32@,4@H_301_32@,[64@H_301_32@,0@H_301_32@,[2@H_301_32@,0@H_301_32@] ]
//var board:[[Int]] = [ [1024,16,2,0],[256,[64,[2,0] ]@H_301_32@
//var board:[Array<Int>] = = [ [1024,0] ]@H_301_32@
//var board:Array<[Int]> = [ [1024,0] ]@H_301_32@
//var board:Array<Array<Int>> = [ [1024,0] ]@H_301_32@


// 二维数组获取元素@H_301_32@
board[0@H_301_32@]
board[0@H_301_32@][0@H_301_32@]


// 获取二维数组两个维度的信息@H_301_32@
board.count
board[0@H_301_32@].count


// Swift中的二维数组,每一维度的元素数目可以不同@H_301_32@
board[0@H_301_32@].append@H_301_32@(0@H_301_32@)
board


// 为二维数组的第一个维度添加的元素是一个数组@H_301_32@
board.append@H_301_32@([0@H_301_32@,0@H_301_32@])
board += [ [0@H_301_32@,0@H_301_32@] ]
board

NSArray

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

//默认这样声明,不加类型,就是声明一个 NSArray@H_301_32@
var@H_301_32@ Narray1 = []

// 用as 关键字转换@H_301_32@
var@H_301_32@ Narray2 = [1@H_301_32@,5@H_301_32@] as@H_301_32@ NSArray

//显示的声明@H_301_32@
var@H_301_32@ Narray3: NSArray = [1@H_301_32@,"hello"@H_301_32@]

var@H_301_32@ Narray4: [NSObject] = [1@H_301_32@,"hello"@H_301_32@]

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

原文链接:https://www.f2er.com/swift/323120.html

猜你在找的Swift相关文章