Swift Array 元素個數判斷爲0的方法哪一種更好

在平常開發中,常常會遇到判斷一個Array中元素個數是否爲0。通常來講,有兩種方法,一種是isEmpty,一種是array.count == 0。那哪種方法更好呢?在蘋果的官方文檔中,isEmpty方法上有這樣一段註釋git

/// When you need to check whether your collection is empty, use the `isEmpty` property instead of checking that the `count` property equal to zero. 
 /// For collections that dont conform `RandomAccessCollection`, accessing the `count` property iterates through the elements of the collection.
 - Complexity: O(1)
複製代碼

大體意思就是,當判斷你的集合是否爲空時,推薦使用isEmpty屬性來代替判斷count屬性是否等於0。由於集合類型的count屬性會遍歷集合裏的全部元素。isEmpty屬性的時間複雜度爲O(1)。 接下來咱們就從源代碼角度來分析一下這2者的區別吧。如下的代碼位於githubstdlib/public/core/Collection.swift文件裏。github

public protocol Collection: Sequence {
	var isEmpty: Bool { get }
	var count: Int { get }
	
	var startIndex: Index { get }
	var endIndex: Index { get }
}
複製代碼

首先,isEmptycount都是Collection協議的計算型屬性。其次,都有一個默認實現。swift

isEmpty 實現

extension Collection {
	public var isEmpty: Bool {
   		return startIndex == endIndex
  	}
}
複製代碼

isEmpty方法的實現很簡單,判斷startIndexendIndex是否相等就能夠了。那startIndexendIndex又是2個計算型屬性,那麼這2個的實現又是怎麼樣的呢?在這個文件裏咱們沒有找到默認實現,因此咱們就前往同層文件夾的Array.swift文件裏去查看一下了。 startIndex的實現很簡單,直接返回了一個0bash

public var startIndex: Int {
    return 0
  }
複製代碼

endIndex的相對就稍微複雜一點了dom

@inlinable
public var endIndex: Int {
	@inlinable
    get {
      	return _getCount()
    }
 }
  
internal func _getCount() -> Int {
	return _buffer.count
}
複製代碼

看到這兒,裏面的再看下去就太深了(我也看不明白了),姑且看成_bufferArray類型的內部實現吧。ui

count 實現

public var count: Int {
	return distance(from: startIndex, to: endIndex)
}

public func distance(from start: Index, to end: Index) -> Int {
    _precondition(start <= end,
                  "Only BidirectionalCollections can have end come before start")
    
    var start = start
    var count = 0
    while start != end {
        count = count + 1
        formIndex(after: &start)
    }
    return count
}
複製代碼

count方法內部調用了一個distance(from:to:)的方法,並且在distance內部有一個while循環遍歷直到start==end,那麼count的事件複雜度就是o(n)spa

所以2個屬性相比,在使用的時候,最好仍是使用isEmpty屬性判斷Array元素是否爲空。code

相關文章
相關標籤/搜索