Swift - 集合类型 - Array

在Swift中仍然保留了OC中的三种集合类型:
Array:数组是有序的值集合。
Set:集合是惟一值的无序集合。
Dictionary:字典是键值关联的无序集合。


CollectionTypes.png

Arrays, sets, and dictionaries in Swift are always clear about the types of values and keys that they can store. This means that you cannot insert a value of the wrong type into a collection by mistake. It also means you can be confident about the type of values you will retrieve from a collection.
在Swift中,数组、集合和字典的值得数据类型很明确。这意味着您不能将错误类型的值插入到集合中。
它还意味着您可以对从集合中检索到的值类型有信心。

Swift’s array, set, and dictionary types are implemented as generic collections.
Swift的数组、集合和字典类型被实现为泛型集合。

If you create an array, a set, or a dictionary, and assign it to a variable, the collection that is created will be mutable. This means that you can change (or mutate) the collection after it’s created by adding, removing, or changing items in the collection. If you assign an array, a set, or a dictionary to a constant, that collection is immutable, and its size and contents cannot be changed.
如果您创建一个数组、一个集合或一个字典,并将其赋值给一个变量,那么所创建的集合将是可变的。这意味着您可以通过在集合中添加、删除或更改项目来更改(或更改)集合。如果您将数组、集合或字典赋值给常量,那么该集合是不可变的,它的大小和内容不能被更改。

看到了官网对于Swift中集合的各种特性解释,接下来我们进入实践阶段,来验证它是否是这样的。

Arrays

Arrays的初始化

在创建之初,我们首先要想好,是需要可变的还是不可变的。
一般来说我们使用不可变的会增加我们程序的安全性,避免了我们在编写程序时无意中添加或者删除了某值造成不好的效果,但系统却没有给出相应的提示。

let someNumber = [3,42,5]
print(someNumber)
结果:
[3, 42, 5]

在这一段程序中,我们直接将3,42,5三个int类型的值加入到了someNumber数组中去了。
在这过程中swift还需要动态的去判断值的类型。
所以我们也可以直接指定它的数据类型:

let someNumber:[Int] = [3,42,5]

这样的一个好处就是我们可以很容易的去识别一个数组当中值得类型是否正确:

let someNumber:[Int] = [3,"Str",5]

当你这样写的时候,编译就会发生错误,因为"Str"是String类型并不是Int类型,程序就会及时的给予你提示。

然而上面的方式其实是一种简写的方式,完整的写法应该如下所示:

let someInts = [Int](arrayLiteral: 3,3,5)
print(someInts)

let arrayInts = Array(arrayLiteral: "3","3","3")
print(arrayInts)

我们再看其他的初始化方式:
创建一个空的数组

var someInts = [Int]()

这里要注意的就是[Int]它的数据类型不能省.不然会报错。
因为Swift中严格的数据类型控制。可以设想,这里没有数据类型控制的话,那么我们在之后的追加元素的操作中,
追加了不同的数据,而我们之前又没有显示的去设定它的数据类型,就会造成数据类型不可控的情况,这个在Swift并不被允许。
你可以通过append去追加元素(当然了,首先你的数组是个变量,而不是常量):

someInts.append(3)

同时,如果你已经初始化完毕,那么你可以直接设定你的数组为空:

someInts = []

你可能会有疑问,为什么一开始的时候不能这样设置为空呢?
因为在这里虽然你设为了空,someInts的数据类型还是Int,你仍然是无法去添加其他类型的值的。

var someInts = [Int]()
someInts.append(3)
someInts = []
someInts.append("string")  //error:Cannot convert value of type 'String' to expected argument type 'Int'
print(someInts)

我们再看看其它的初始化方式:

let threeDoubles = Array(repeatElement(0.0, count: 3))
print(threeDoubles)
结果:
[0.0, 0.0, 0.0]

其实从参数名称上我们就可以知道,我们创建了3个重复值用于数组的初始化。
repeatElement方法中可以填写两个参数,一个是需要重复的数据,count表示重复多少次。
我想,这是为了方便我们在特定情况下的初始化吧。

嗯,继续看看别的初始化方式:
我们在使用的时候,默认的数据的类型的确是确保了我们的数据类型安全,但同时也限制了我们编程的灵活性。
在很多实际的运用场景中,一个数组集合中包含的并不可能只有一种数据类型的值,如果每一种都需要定义个数组来进行操作的话,也会增加开发成本。当然咯,这个还是根据具体的环境来决定成本的舍取性的。
那么如何去定义一个什么类型都可以存的数组呢?

let anyData = ["String",34,53] as [Any]
print(anyData)
结果:
["String", 34, 53]

通过结果我们可以看到,这样定义的数组可以容纳其他类型的值。

初始化我们大概了解了之后,我们还需要了解它的内置方法:

Array的内置方法

first 获取第一个元素

var shopping_list = ["A","B","C","D"]
print(shopping_list.first)
结果:
"A"

first where 根据判断条件返回结果

var shopping_list = [53,4,2,45]
let result = shopping_list.first(where: { (intResult) -> Bool in
    return intResult==54
})
print(result ?? 0)

这里的意思是如果第一个元素是54,那么返回正确结果,如果不是的话本来是应该返回nil的,但是我们给它做了判断,如果为nil,那么结果为0。

last 获取最后一个元素

var shopping_list = ["A","B","C","D"]
print(shopping_list.last)
结果:
"D"

count 数量

let shopping_list = [3,4,2,3]
print("The shopping_list list contains \(shopping_list.count) items.")
结果:
The shopping_list list contains 4 items.

isEmpty 判空

let shopping_list = [3,4,2,3]

if shopping_list.isEmpty {
    print("The shopping_list list is empty.")
} else {
    print("The shopping_list list is not empty.")
}
结果:
The shopping_list list is not empty.

contains 判断数组中是否包含某个元素

var shopping_list = ["A","B","C","D"]
print(shopping_list.contains("C"))
结果:
true

append 追加

var shopping_list = [1]
shopping_list.append(4)
print(shopping_list)
结果:
[1,4]

insert(newElement: at: ) 插入单个元素
将新元素插入到指定的位置,但不能插入到数组最后一位的下一位。

var shopping_list = [1]
shopping_list .insert(3, at: 1)
print(shopping_list)
结果:
[1,3]

insert(contentsOf:at:) 插入整个集合

var shopping_list = [1,2]
var otherShopping_list = [3,4,5]
shopping_list.insert(contentsOf: otherShopping_list, at: 2)
print(shopping_list)
结果:
[1,2,3,4,5]

replaceSubrange(Range<Int>, with: Collection) 将某个范围的元素替换为指定的集合

var shopping_list = ["A","B","C","D"]
shopping_list.replaceSubrange(0...1,with:["F","E"])
print(shopping_list)
结果:
 ["F","E","C","D"]

remove(at:) 移除某个下标的元素

var shopping_list = [1,2,3,4]
shopping_list.remove(at: 0)
print(shopping_list)
结果:
[2,3,4]

removeFirst(count) 从开始位置开始移除指定数量的元素

var shopping_list = [1,2,3,4]
shopping_list.removeFirst(2)
print(shopping_list)
结果:
[3,4]

removeLast(count) 从末尾位置开始向前移除指定数量的元素

var shopping_list = [1,2,3,4]
shopping_list.removeLast(2)
print(shopping_list)

removeFirst() 移除第一个元素

var shopping_list = [1,2,3,4]
shopping_list.removeFirst()
print(shopping_list)
结果:
[2,3,4]

removeLast() 移除最后一个元素

var shopping_list = [1,2,3,4]
shopping_list.removeLast()
print(shopping_list)
结果:
[1,2,3]

removeSubrange(Range) 移除某个范围内的元素

var shopping_list = [1,2,3,4]
shopping_list.removeSubrange(0...1)
print(shopping_list)
结果:
[3,4]

0...1 表示 [0,1] 的区间,即包含0和1的范围

removeAll() 移除所有

var shopping_list = [1,2,3,4]
shopping_list. removeAll()
print(shopping_list)
结果:
[]

移除数组中全部元素,有一个可选参数,keepCapacity。如果keepCapacity = YES的话,那么数组移除元素后,其存储空间还是存在的,在此往里存储值,不需再给他分配存储空间了。如果keepCapacity=NO的话,那么数组的存储空间就会被回收掉。

var shopping_list = [1,2,3,4]
shopping_list. removeAll(keepCapacity: true)
print(shopping_list)
结果:
[]

数组的遍历

比较常见的就是for-loop遍历了。

var shopping_list = [1,2,3,4]
for item in shopping_list {
    print(item, terminator: "")
}
结果:
1234

还有一种方式是枚举遍历法,我们有时也会称之为迭代器遍历

官网中这样解释到:

If you need the integer index of each item as well as its value, use the enumerated() method to iterate over the array instead. For each item in the array, the enumerated() method returns a tuple composed of an integer and the item. The integers start at zero and count up by one for each item; if you enumerate over a whole array, these integers match the items’ indices. You can decompose the tuple into temporary constants or variables as part of the iteration:
如果您需要这个项目的每一个值和索引,那么可以使用enumerated()方法来迭代该数组。对于数组中的每个项,enumerated()方法返回一个由一个整数和项组成的元组。整数从零开始,每一项都是一;如果您对整个数组进行枚举,那么这些整数将匹配项目的索引。您可以将元组分解为临时常量或变量,作为迭代的一部分:

var shopping_list = ["A","B","C","D"]
let enumerated_list = shopping_list.enumerated()
for (index, value) in  enumerated_list {
    print("Item \(index + 1): \(value)")
}
结果:
Item 1: A
Item 2: B
Item 3: C
Item 4: D

其中可以看到index就是它的索引,value是它的值。

sorted 排序

var shopping_list = [53,4,2,45]
for item in shopping_list.sorted(){
    print(item,terminator: " ")
}
结果:
2 4 45 53 

sorted by 有条件的排序

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