[置顶] swift Array 数组 总结


/*

编程环境: xcode 7.0 beta6

*/




/*---------------------------.数组的创建-------------------------*/

//[someType]  等同于 Array<someType>,都代表可以装有someType这种类型数据的数组,下边我只使用[someType]这种形式:


/*

1. 变量数组,常量数组

变量数组可以进行更改,对应OC可变数组:NSMutableArray,常量数组不可以进行修改, 对应OC不可变数组:NSArray

*/

var arr1_1:[Int]     //变量数组

let arr1_2: [Int]    //常量数组,可以不直接赋值, 但是当第一次赋值过后就不可以更改了


/*

2. 数组的创建你可以指定这个数组装有什么类型,如果你指定特定的类型, 那么这个数组只能装这个类型的数据,或者这个类型的子类的数据;

*/

let arr1_3: [String] = ["ab","cd"] //只能添加字符串类型


/*

3. 如果你不指定的类型, swift会有类型推断,根据你在等号右边赋的值来进行类型推断:

*/

//(1). 如果赋的值都是某个特定类型的数据,比如说都是[1, 2, 3], 那么类型推断为[Int];

var arr1_4 = [1,2, 3]    //这时arr1_4[Int]类型

arr1_4 = []              //这种情况, arr1_4依旧是[Int]类型


//(2). 如果你所赋的值都为NSObject类的对象或者继承与NSObject类的对象,或者String, Int, Double等一些基础类型, 那么swift将这个数组推断为[NSObject]类型;

let NSStr1_1: NSString ="NSString"

let arr1_5 = [1,"123", NSStr1_1]   //这时arr1_5[NSObject]类型


//(3). 如果数组中包含不止继承与NSObject类的数据(没有任何继承与任何类的对象),或者不继承与NSObject又不是基础类型数据,比如说Array Dictionary, swift将其推断为NSArray类型(原来是OC中的类型, swift中一样有这个类型, 实现了部分OC中的方法), NSArray这个类型可以和swift中的[Element]相互转换, [Element](这个涉及到泛型, 就是一个占位类型, 你往数组添加任何类型的数据都可以);

let arr1_6 = [1,"123", arr1_5]   //识别为NSArray类型

let arr1_7 = Array(arr1_6)        //将其转换为[Element]类型,注意[Element]这个类型不可以直接声明;

/*如果想得到一个,空的泛型数组可以这样写:*/

let arr1_8 = []             //这个时候识别为NSArray类型

var arr1_9 = Array(arr1_8//arr1_9就是一个空的[Element]类型的数组


//4. 创建一个有多个元素重复的数组

var arr1_10 = Array(count:3, repeatedValue: 1.3)

print(arr1_10)

/*打印结果

[1.3, 1.3, 1.3]  //含有3 1.3的数组

*/


//5. 通过两个数组相拼接的方式获取新数组

var arr1_11 = arr1_7 + arr1_9//等号后边两个数组必须是相同类型的数组,比如这两个都是泛型数组[Element]

print(arr1_11)

/*打印结果

[1, 123, (

1,

123,

NSString

)]

*/


//6. 通过 Array(arrayLiteral: <#T##Element...##Element#>)来创建数组:

var NSStr1_2: NSString ="NSString2"

let arr1_12 = Array(arrayLiteral:1, "123",1.23, NSStr1_2)     //这后边只能填NSObject类的对象或者继承与NSObject类的对象,以及Int, Double, String 一些基础类型,这时arr1_12被识别为[NSObject]类型


//7. 通过范围运算符 0...1来创建数组:

//0...1 表示 0 1 的开区间(0..<1表示0 1 的半开半闭区间,不包括1)

let arr1_13 = [0,1, 2, 3, 4, 5]

var arr1_14 = arr1_13[0...3]   //这个时候arr1_14ArraySlice类型(ArraySlice类型和Array类型很像,像截取数组的一部分的时候, 都会被识别为ArraySlice类型,可以被理解为迷你版的Array, Array ArraySlice 类型和可以相互转换)

var arr1_15 = Array(arr1_14)  //转换为Array<Int>类型




/*---------------------------.遍历数组-------------------------*/


//1 首先说一下如何查看数组的元素,以及获取数组的一些基础属性

var arr2_1 = [999,10, 99, 4]

//(1)首先说一下数组名[下标]的方式来访问或者修改数组元素 eg:

print(arr2_1[0])

/*打印结果

999

*/


arr2_1[0] =110

print(arr2_1)

/*修改后的打印结果

[110, 10, 99, 4]

*/


//(2)通过0...1(这个表示0 1 的开区间)的这种范围方式来访问数组:

print(arr2_1[0...1])

/*打印结果

[110, 10]

*/


//(3)获取数组某些特定位置的元素:

print(arr2_1.first)    //获取数组的第一个元素    打印结果: Optional(110)

print(arr2_1.last)     //获取数组的最后一个元素  打印结果: Optional(4)


//(4)获取数组元素的数量:

print(arr2_1.count)   //打印结果: 4


//2. for in 数组遍历

//(1)for in 遍历全部元素

for id in arr2_1 {

    print(id)

}

/*打印结果

999

10

99

4

*/


//(2)for in 遍历数组某一个区间的元素

for id in arr2_1[1...3]{

    print(id)

}

/*打印结果:

10

99

4

*/


//3. for 循环数组遍历

for var i =0; i < arr2_1.count; ++i {

    let id = arr2_1[i]

    print(id)

}

/*打印结果

999

10

99

4

*/


//4. 使用枚举法,进行遍历

for (a, b) inarr2_1.enumerate(){

    print("\(a) =\(b)")

}

/*打印结果

0 = 999

1 = 10

2 = 99

3 = 4

*/


//5. 模拟系统给出的枚举法遍历数组

var en = arr2_1.enumerate().generate()

var temp: (Int,Int)? = en.next()

while temp !=nil {

    print(temp!)

    temp = en.next()

}

/*打印结果

(0, 999)

(1, 10)

(2, 99)

(3, 4)

*/




/*---------------------------.给数组添加元素-------------------------*/

//1. 在数组的后边添加一个元素

var arr3_1 = ["hello"]

arr3_1.append("world")

print(arr3_1)

/*打印结果:

[hello, world]

*/


//2. 在数组的某个位置添加元素:

arr3_1.insert("my", atIndex:1)

print(arr3_1)

/*

[hello, my, world]

*/


//3.使用 +=给数组拼接另一个数组在老版本是可以使用 +=拼接一个元素的, 但这个版本把这个功能去掉了

arr3_1 += ["codeWorm","dear"]

print(arr3_1)

/*打印结果:

[hello, my, world, codeWorm, dear]

*/


//4. 在数组的某个index位置,添加一个相同类型的数组:

arr3_1.insertContentsOf(["123","456"], at:0)

print(arr3_1)

/*打印结果:

["123", "456", "hello", "my", "world", "codeWorm", "dear"]

*/




/*---------------------------.删除数组的元素-------------------------*/

var arr4_1 = [1,2, 3, 4, 5]


//1. 删除最后一个元素,返回值为被删除的元素

let remove1 = arr4_1.removeLast()

print(arr4_1)

/*打印结果

[1, 2, 3, 4]

*/


//2. 删除某个index的元素,返回值为被删除的元素

let remove2 = arr4_1.removeAtIndex(0)

print(arr4_1)

/*打印结果

[2, 3, 4]

*/


//3. 删除某个范围的元素

arr4_1.removeRange(Range(start:0, end: 1))

print(arr4_1)

/*打印结果

[3, 4]

*/


//4. 删除数组的所有元素,并且不保留数组所占的空间

arr4_1.removeAll()


//5. 删除数组的所有元素,但是所占的内存空间将被保留

arr4_1.removeAll(keepCapacity:true)




/*---------------------------.修改数组的元素-------------------------*/

var arr5_1 = [1,2, 3, 4, 5, 6,7]


//1. 可以用数组名[下标数]这种形式 来修改某个index的元素值

arr5_1[0] =99 //将第0个元素的值修改为99

print(arr5_1)

/*打印结果

[99, 2, 3, 4, 5, 6, 7]

*/



//2. 将数组某个范围的元素替换为后面的这段数组的元素,注意这个范围最大数不能超过数组的count - 1否则会运行时崩溃

arr5_1[1...3] = [100,101, 102]

print(arr5_1)

/*打印结果

[99, 100, 101, 102, 5, 6, 7]

*/


//3. 使用 arr5_1.replaceRange(<#T##subRange: Range<Int>##Range<Int>#>, with: <#T##C#>) 来替换元素, 这里第一个参数为范围, 第二个参数是要替换的数组或者表示数组的指针

arr5_1.replaceRange(Range(start:0, end: 4), with: [0,1, 2, 3, 4])

print(arr5_1)

/*打印结果

[0, 1, 2, 3, 4, 5, 6, 7]

*/


//replaceRange 替换UnsafeMutableBufferPointer数组的指针类型:

var arr5_2 = [999,1000, 1001]

var pointer = UnsafeMutableBufferPointer<Int>(start: &arr5_2, count:arr5_2.count)    //这是用来表示字符串的指针类型

arr5_1.replaceRange(0..<1, with: pointer)    //第一个参数range的另一种表现形式, 0 1 的半开半闭区间(0...1 表示0 1的开区间), 这里也就是表示, arr5_1的第0个元素替换成这个数组指针对应数组的元素

print(arr5_1)

/*打印结果

[999, 1000, 1001, 1, 2, 3, 4, 5, 6, 7]

*/





/*---------------------------.对于数组的一些基础的判断-------------------------*/


//1. 判断数组是否为空

var arr6_1: [Int] = []

print(arr6_1.isEmpty)//判断的前提是数组已经被实例化

/*打印结果

true

*/


//2. 判断数组是否包含某个元素:

var arr6_2 = ["hello","world", "I","am", "code"]

//(1)可以直接这么调用:

print(arr6_2.contains("hello"))

/*打印结果

true

*/

//(2) 可以使用闭包为参数进行判断

let isContain =arr6_2.contains { (obj) -> Boolin      //这个运行原理就是,编译器调用你的闭包,将数组内的元素顺次作为闭包的参数传入, 进行判断, 当然判断逻辑是你写的,直到闭包的返回值为true 或者将数组内的所有元素传参完毕闭包调用结束,否则继续传入下一个数组的元素作为参数调用这个闭包,如果闭包的返回值出现为true的情况,contains返回值为true,如果直到闭包调用完毕都没有出现true的情况,contains返回值为false

    if obj == "木哈哈" {

        return true

    }

    return false

}

//简写:

let isContainSam =arr6_2.contains{$0 =="木哈哈"}   //$0 就是第一个参数的意思, $1第二个, 多个参数同理, 当一个闭包只有一个return语句时, return可以省略

print(isContain)

/*打印结果

false

*/




/*---------------------------.数组分割为字符串, 字符串拼接数组-------------------------*/

//这个如果有OC基础就知道这个:

//1. 使用某个字符串来分割字符串,分割结果为数组:

let str7_1 = "www.baidu.com/www.v1.cn/haha"

let arr7_1 = str7_1.componentsSeparatedByString(".")

print(arr7_1)

/*打印结果

["www", "baidu", "com/www", "v1", "cn/haha"]

*/


//2. 使用NSCharacterSet类型来分割字符串:

let arr7_2 = str7_1.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString:"./"))    //分别以. /来分割

print(arr7_2)

/*打印结果

["www", "baidu", "com", "www", "v1", "cn", "haha"]

*/


//3. 将数组拼接成字符串

let str7_2 = arr7_2.joinWithSeparator("我是 (空格)")

print(str7_2)

/*打印结果

www我是 (空格)baidu我是 (空格)com我是 (空格)www我是 (空格)v1我是 (空格)cn我是 (空格)haha

*/




/*---------------------------.数组的一些其他方法-------------------------*/


//1. sortInPlace 排序

var arr8_1 = [2,32, 1, 5, 3, 4]

//sortInPlace方法就是原来的sort方法

arr8_1.sortInPlace { (id1, id2) ->Bool in     //传入闭包的原理类似与将冒泡排序的排序准则传入,编译器来实现冒泡排序, 然后根据你的准则来判断是否交换元素位置, eg:

    if id1 > id2{

        return true

    }

    return false

}

//上边这个可以简写为:

//arr8_1.sortInPlace {$0 > $1}       //$0 就是第一个参数的意思, $1 第二个, 多个参数同理,当一个闭包只有一个return语句时, return可以省略

print(arr8_1)

/*打印结果

[32, 5, 4, 3, 2, 1]

*/


//2. reverse 翻转数组:

let arr8_2 = [9,6, 3, 0, 2, 4,5]

let arr8_3 = Array(arr8_2.reverse())

print(arr8_3)

/*打印结果:

[5, 4, 2, 0, 3, 6, 9]

*/


//3. filter 过滤数组:

let arr8_4 = [-5, -4, -3, -2,0, 1, 2, 3, 4,5, 6, 7, 8]

let arr8_5 = arr8_4.filter{$0 %2 == 0 && $0 >0//过滤出数组中的正偶数

//展开为:

//let arr8_5 = arr8_4.filter { (obj) -> Bool in

//    return obj % 2 == 0 && obj > 0

//}

print(arr8_5)

/*打印结果:

[2, 4, 6, 8]

*/


//4. map 遍历计算数组

let arr8_6 = [1,2, 3, 4, 5]

let arr8_7 = arr8_6.map{$0 *2} //通过计算形成新数组

print(arr8_7)

/*打印结果:

[2, 4, 6, 8, 10]

*/


//5. reduce 方法

let arr8_8 = [2.0 ,9.0]

let result8_1 = arr8_8.reduce(9.0) { (obj1, obj2) ->Double in

    return obj1/obj2

}

//reduce, 需要传一个初始值,这里传的是9.0, 第一次传入闭包两个参数分别为初始值本身 数组的第一个元素,第二次传的两个参数分别为, 第一次闭包的运算结果和数组的第二个元素,直到所有数组的元素全部被运算完毕, 最后一次调用闭包完毕返回的值为最终的值, 这里做的计算也就是: 9.0/2.0/9.0 = 0.5


//简写为:

//let result8_1 = arr8_8.reduce(9.0){$0/$1}    这里涉及到尾随闭包的知识, 在网上搜一下尾随闭包就知道怎么回事了


print(result8_1)

/*打印结果:

0.5

*/




/*---------------------------.数组拷贝-------------------------*/

/*

swift刚一出现的时候,数组是作为引用类型出现的, 虽然作为一个结构体,但是更像是类的对象的性质, 这可见数组的这个结构体的底层不单单是像C语言和OC中在栈区开辟空间去存储值类型那么简单,猜测也是要去堆区开辟空间的, 在后来更新版本中, Array取消了这样的性质,而是只作为值类型出现, 这样就让新学习swift的人来说不会有"为什么值类型还可以做引用的操作?"这样的困惑, 下面是一个eg:

*/

var arr9_1 = [1,2, 3]

var arr9_2 = arr9_1

arr9_2[0] =999

print("arr9_1 =\(arr9_1) arr9_2 =\(arr9_2)")

/*打印结果:

arr9_1 = [1, 2, 3] arr9_2 = [999, 2, 3]

*/


//可见现在的数组是一个值类型了!



你可能感兴趣的:(ios,array,数组,swift,数组方法)