2016-07-15 14:16:47 liuwin7 阅读数 976

1.相遇

有个业务需求,把表格中的数据整合到一个数组中,如下

Name Age Item1 Item2 Item3 Country
Jack 21 32 43 null China
Tom 23 83 67 75 US

整合后的结果是这样

[
    {
        "Name": "Jack",
        "Age": 21,
        "score": [
            {
                "Item1": 32
            },
            {
                "Item2": 43
            }
        ],
        "Country": "China"
    },
    {
        "Name": "Tom",
        "Age": 23,
        "score": [
            {
                "Item1": 83
            },
            {
                "Item2": 67
            },
            {
                "Item3": 75
            }
        ],
        "Country": "US"
    }
]

有个中间的状态,就是把一条记录整合出来之后,取中间的几个元素作为一个整体,所以需要把中间的几个数据切片到一个新的数组中。
之前在学习Swift的时候,了解过一下数组的用法,以为是非常了解了,实则不然。

2.对于切片数组的 subscript ,你了解多少?

一个简单例子

let array = ["A", "B", "C", "D"]
let slicedArray = array[1..<3]
print(slicedArray.count) // 2
print(slicedArray[0]) // error

WHY?

明明数组中有两个元素,但是为什么用subscript访问,却报错呢?
还有

let slicedArray String = slicedArray.reduce("start: ") { (acc, item) -> String in
    "\(acc)\(item)"
}
print(slicedString) // start: BC

很明显这个”数组”中是有数据的呀,怎么就是取不出来呢?

3.startIndex & endIndex

slicedArray 的 startIndex 和 endIndex 是多少呢?

print(slicedArray.startIndex) // 1 instead 0
print(slicedArray.endIndex) // 3

所以,在用[0]访问slicedArray的时候,其实是越界的 out of bounds !!!!

4.怎么解决这个问题

不去详细的解释为什么,这个跟swift对数组的设计理念相关,copy-on-write,目的之一提高性能
两个方案解决这个问题:

  1. 违背swift的设计原则
    直接创建一个新的数组变量

    let lastedArray = Array(array[1..<3])
    print(lastedArray.startIndex) // 0
    print(lastedArray.endIndex) // 2
    print(lastedArray[0]) // B
  2. 使用数组的属性startIndex,endIndex

    combinedArray[combinedArray.startIndex] // B
    combinedArray[combinedArray.startIndex.advancedBy(1)] // C

5.参考文献

  1. swift-subarrays-array-and-arrayslice
  2. swift-array-and-arrayslice-xcode-7.2
2017-08-28 10:36:47 weixin_37633696 阅读数 0

对比Swift 数组与Objective-C

      1. 在Objective-c 中有`NSMutableArray` 和 `NSArray` 区分可变数组和不可变数组,但是 Swift 中通过`let` 和 `var` 
      来区分不可变数组和可变数组
      2. Swift 数组可以使用加法赋值运算符(+=)或者加法运算符(+)来添加拥有相同类型的数组
      3. Swift 中数组是类型安全的,所以在某个数据被存入到某个数组之前类型必须明确。
     (比如我们创建了一个String类型的数组,那么这个数组中只能添加String类型的数据不能添加其他的数据类型)

1.数组的创建

1)Swift 中定义数组通常有两种格式

 Array<Element>
 [Element]

代码示例如下

var arr1 : Array<String>
var arr2 : [String]

2)用字面量构造数组
let 常量名 : [类型] = [value1,value2,value3,value4]
let 常量名 = [value1,value2,value3,value4]
代码示例

let array1 : [String] = ["1","2","3","4"]
let array2 : [Any] = [1,2,"1"]
let arr3 = [1,2,3]

3)两个数组相加创建新的数组

var array3 = ["1","2","3"]
var array4 = ["4","5","6"];

let array5 = array3 + array4

输出
这里写图片描述

注意:数组对于存储数据有具体的要求,数据元素被存储到某个数组中时,必须通过 显示类型标注或者类型推断 声明数据类型

2.数组的常见操作

2.1 获取数组的长度

let arr4 = [1,2,3,4,5,6]
let length = arr4.count

输出
这里写图片描述

2.2数组的遍历

let arr5 = ["11","22","33","44"]
for element in arr5 {
    print(element);
}

输出
这里写图片描述

3.数组的增加 和 删除

3.1定义一个可变数组

var nameArr = ["张三","王二小"]

—————— 增 加 ——————

3.2 在数组末尾增加一个元素

nameArr.append("李四");

这里写图片描述
3.3数组的指定位置插入一个元素

nameArr.insert("小淘气", at: 2)

这里写图片描述
—————— 删 除 ——————
3.4删除指定位置的元素

nameArr.remove(at: 1);

这里写图片描述
3.5删除数组第一个元素

nameArr.removeFirst()

这里写图片描述
3.6删除数组最后一个元素

nameArr.removeLast()

这里写图片描述
3.7删除全部元素

nameArr.removeAll()

这里写图片描述

4.数组的修改 和 下标查询

—————— 修 改 ——————
4.1修改数组指定下边位置的元素

var nameArr = ["one","two","three","four"]
nameArr[0] = "11"

这里写图片描述

4.2使用下标语法修改多个元素

nameArr[1...2] = ["22","33"]

这里写图片描述

—————— 查 询 ——————
4.3 使用下标语法查询单个

nameArr[2]

这里写图片描述

4.4 使用下标语法查询多个元素

nameArr[1...2]

这里写图片描述

2016-09-21 14:59:01 a645258072 阅读数 0

去年学习了一小段时间的 Swift ,但是由于项目一直使用OC,又加上工作一直很忙,所以慢慢的 Swift 也就忘记了。直到最近,打算重新学习 Swift。从现在开始,从基本的语法开始。防止以后不用Swift,又再次忘记。  注意: 此处为iOS 9代码,iOS 10可能会不适配

        var mutableArray:[Int] = []                        // 创建一个存储Int类型的可变数组
        let otherArray = [22,24]                           // 创建一个不可变的Int类型数组
        
        for i in0...20 {
            mutableArray.append(i)                         // 将 i添加到 mutableArray中,相当于 OC的 addObject
        }
        mutableArray.insert(100, atIndex:10)               // 向 mutableArray数组的第下标为3的位置上,插入 100
        let first = mutableArray.first                     // 获取 mutableArray数组的第一个元素
        let last = mutableArray.last                       // 获取 mutableArray数组的最后一个元素
        let five = mutableArray[5]                         // 获取 mutableArray数组,下标为 5的元素
        let isEmpty = mutableArray.isEmpty                 // 判断数组是否为空,为空返回 true不为空返回 false
        let sumArray = mutableArray + otherArray           // 两个数组合并,返回新的数组
        let flipArray = sumArray.reverse()                 // 数组元素反转,返回新的数组
        
        let flipFirst = flipArray.first                    // 获取反转后的数组的第一个元素
        let removeLast = mutableArray.removeLast()         // 删除 mutableArray数组的最后一个元素
        let removeIndex = mutableArray.removeAtIndex(2)    // 删除 mutableArray数组下标为2的元素
        mutableArray.removeAll()                           // 清空数组
        
        let removeisEmpty = mutableArray.isEmpty
        
        debugPrint("mutableArray:\(mutableArray)")
        debugPrint("first:\(first)")
        debugPrint("last:\(last)")
        debugPrint("five:\(five)")
        debugPrint("isEmpty:\(isEmpty)")
        debugPrint("sumArray:\(sumArray)")
        debugPrint("flipArray:\(flipArray)")
        debugPrint("flipFirst:\(flipFirst)")
        debugPrint("removeLast:\(removeLast)")
        debugPrint("removeIndex:\(removeIndex)")
        debugPrint("mutableArray:\(mutableArray)")
        debugPrint("remove isEmpty:\(removeisEmpty)")

这里只记录了常用的方法,但是又担心会忘记的方法。

 值得注意的一点: 反转后的数组是一个不可变数组,只能获取元素,而不能对元素进行操作(比如删除某个元素)

2015-08-19 14:26:42 CHENYUFENG1991 阅读数 11554

      Array是Swift中的数组数据类型,而NSArray是OC中的数组数据类型,两者有区别有联系。在Swift中有时候难免会使用到OC中的一些东西,今天我们就来Swift中使用NSArray和Array,并且进行转化。

(1)声明一个Array数组,并进行遍历,代码如下:

    let stringArray: Array<String> = ["10", "20","30","40","50"]
        for index in stringArray{
        
            println(index)
        }
        

输出结果如下:

使用Swift遍历Array数组没有任何问题,可以使用for...in循环。


(2)声明一个NSArray数组,并进行遍历,代码如下:

     let stringNSArray: NSArray = ["10", "20","30","40","50"]
        
        for index in stringNSArray{
        
            println(index)
        }

输出结果如下:

可见NSArray数组也可以在Swift中直接进行声明并进行遍历。


(3)声明一个NSArray数组,转化为Array数组,再进行遍历:

   let stringNSArray: NSArray = ["10", "20","30","40","50"]
        let stringArray:[String] = stringNSArray as! [String]
        
        for index in stringArray{
        
            println(index)
        }

输出结果如下:


可见NSArray可以在类型转换后直接赋值给Array数组,然后也可以进行遍历。


(4)声明一个Array数组,转化为NSArray,再进行遍历:

     let stringArray: Array<String> = ["10", "20","30","40","50"]
        let stringNSArray:NSArray = stringArray
        for index in stringNSArray{
        
            println(index)
        }

输出结果如下:

可以看到Array数组也可以直接转化为NSArray,并进行遍历。             


      总结,Swift在数组方面Array很好的兼容了OC中的NSArray。可以直接进行赋值转换。


github主页:https://github.com/chenyufeng1991  。欢迎大家访问!














2016-07-21 09:25:14 mydo 阅读数 3136

我们知道Swift可以扩展已存在的类或结构,这些类或结构可以存在于标准库(或称为核心库)中.如果结构是一个集合类型(比如Array)就更有趣了.我们想尝试写一个限定Type数组的扩展,So我们就拿Array< Int>为例吧.

本猫想是不是可以这么写:

extension Array<Int>{
    //....
}

不过显然不可以 :[

翻看了一下Apple官方的Swift编程语言,一无所获.于是上网溜了一圈,发现一个可行的解决方法,是滴,必须要用where子句:

extension _ArrayType where Element == Int{
    func count(index:Int)->Int{
        print("In _ArrayType")
        return 11*11
    }
}

[1,2,3].count(2)
["1"].count(2) //error!!!

主要思想是我们不能直接拿Array开刀,但是可以间接用_ArrayType类型,可以看到最后一行代码出错,因为它是一个[String]型的数组.

不过别高兴太早了,上面的代码在Swift3中行不通,因为Swit3中压根就找不到_ArrayType类型 ;(

然而车到山前必有路,不能从Array入手,我们可以间接从其遵循的协议入手.于是在Swift3中有两种方法可以达到目的:

extension Sequence where Iterator.Element == Int{
    func count(index:Int)->Int{
        print("In Sequence")
        return index * index
    }
}

extension Collection where Iterator.Element == Int{
    func count(index:Int)->Int{
        print("In Collection")
        return index * index
    }
}

需要注意的是如果要把以上代码用在Swift2.x中需要在Sequence和Collection后面加上Type:

SequenceType
CollectionType

值得一提的是如果我们希望Array扩展中的元素遵循某个协议(而不是等于某种类型)的话可以这么写:

protocol Lovable{
    func fallInLove(with name:String)
}

struct Love:Lovable{
    func fallInLove(with name:String){
        print("fall in love with \(name)")
    }
}

extension Array where Element:Lovable{
    func count(index:Int)->Int{
        print("In Array")
        return index * index
    }
}

let loves = [Love(),Love()]
loves.count(index: 12)