2016-03-09 59 views
1

我有這個Apple代碼庫的代碼,我想了解map()方法是如何工作的。在swift中使用map()方法2.1

let digitNames = [ 
    0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four", 
    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine" 
] 
let numbers = [16, 58, 510] 


let strings = numbers.map { 
    (var number) -> String in 
    var output = "" 
    while number > 0 { 
     output = digitNames[number % 10]! + output 
     number /= 10 
    } 
    return output 
} 

在它被寫入,所述封閉計算
最後數字「編號」使用%提醒操作者,這數字 (這是變種數目)被用來
說明書查找'digitNames'中的合適的字符串。

爲什麼它會計算'number'的最後一位數字而不是第一個數字? '輸出'字符串是如何構建的?

我的理解是 第一次迭代: 而編號= 1,輸出= [「一個」] 和數目/ 10 = 0 因爲位1是「digitNames」詞典中的有效密鑰,和「編號」等於0
封閉將返回「一個」。 現在,地圖()方法被調用的「數字」陣,它會增加「一」到「輸出」

請問map()方法只關閉返回添加到「輸出」
數組一次'數'= 0還是在將閉包返回添加到'輸出'之前檢查輸出值是否包含在 '數'中?

我的理解,即使它不能是正確的是: 對數= 1 ... 9 數/ 10等於0,因此while循環條件被滿足
數> 0和閉合將返回'輸出'作爲數字+輸出並且構建「OneTwoThree」。 因此對於

number = 1, output = [One] 
number = 2, output = [OneTwo] 

等等。

您能逐步描述代碼的流程以及它的工作原理嗎?

+0

你問'map'還是關於_this code_中'map'後面大括號內的東西? – matt

+0

@matt我在問** map **方法在應用於閉包時作爲唯一參數時的工作方式。 – bibscy

+0

好吧,我不知道什麼時候應用在封閉上的意思,但看看我的答案,看看是否有幫助。 – matt

回答

1

map方法遍歷數組(或類似於數組的東西),併爲數組的每個元素循環返回一個新值。那些返回的值形成一個新的數組,這是map方法的結果。因此,原始數組的每個元素都將映射到新數組的元素。

map方法知道什麼與原數組的每個元素做的方式是你提供的一個功能(通常,雖然不一定,匿名函數)。該函數處理原始數組的一個元素,並返回一個值以給出新數組的相應元素的映射值。

所以,在遊樂場玩耍,你會發現[1,2,3,4].map{$0*2}[2,4,6,8]。爲什麼?因爲我們循環遍歷數組[1,2,3,4]和我們提供的函數,對於每個元素,返回該元素乘以2。

也許這將幫助,如果我寫的更冗長這樣的:

[1,2,3,4].map { 
    anElement in 
    return anElement * 2 
} 

甚至冗長爲:

func multiplyBy2(anElement:Int) -> Int { 
    return anElement * 2 
} 
[1,2,3,4].map (multiplyBy2) 

你可以看到,這樣的話也爲蘋果的例子。同樣,如果我將地圖功能表示爲實際功能並在我使用它之前單獨試用它可能會有幫助作爲地圖功能。所以:

let digitNames = [ 
    0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four", 
    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine" 
] 
func wordify(number:Int) -> String { 
    var output = "" 
    var number = number 
    while number > 0 { 
     output = digitNames[number % 10]! + output 
     number /= 10 
    } 
    return output 
} 

好吧,讓我們嘗試在幾個數字

wordify(16) // "OneSix" 
wordify(58) // "FiveEight" 
wordify(510) // "FiveOneZero" 

好吧,讓我們用它在map

let numbers = [16, 58, 510] 
numbers.map(wordify) // ["OneSix", "FiveEight", "FiveOneZero"] 

的結果是完全一樣的,如果我們」 d將函數分別應用於數組的每個元素,並組合成一個數組 - 正如我們所期望的那樣。

1

地圖是高階函數該陣列上調用時將產生一個新的數組(可能是不同類型的),其中所有的元素是原始陣列的每個元件上預先形成的特定操作的結果。因此,我們將看看它的類型簽名(注意,這是完全超過簡化,這樣我們可以專注於地圖):

class [T] { 
    func map<T, U>(T -> U) -> [U] 
} 

注:其重要的你瞭解泛型類型的迅速的概念來理解這個例。

所以map是一種對[T]類型(這只是Array<T>的語法糖)類型的數組進行操作的方法。我們可以看到該地圖需要關閉T -> U這意味着給定一種類型,它可以返回另一個類型Int -> StringDouble -> Double

從類型簽名我們可以看到該映射返回一個類型爲[U]的數組。因此,它從原始數組中獲取每個元素並將其提供給閉包,該閉包返回U類型的結果,然後將結果添加到結果中。