2016-03-22 85 views
8

我已經更新了Xcode(7.3),並且有很多更改;類似C的表達式將被棄用。舉個簡單的例子,如何在Swift 2.2+中編寫非C類for循環?

for var i = 0; i <= array.count - 1; i++ 
{ 
     //something with array[i] 
} 

我該如何編寫這個清晰,簡單的C樣for循環以符合新的更改?

for var i = 0, j = 1; i <= array.count - 2 && j <= array.count - 1; i++, j++ 
{ 
    //something with array[i] and array[j] 
} 

更新。 一個多種變異

for var i = 0; i <= <array.count - 1; i++ 
{ 
    for var j = i + 1; j <= array.count - 1; j++ 
    { 
     //something with array[i] and array[j] 
    } 
} 

更多...

for var i = 0, j = 1, g = 2; i <= array.count - 3 && j <= array.count - 2 && g <= array.count - 1; i++, j++, g++ 
{ 
    //something with array[i] and array[j] and array[g] 
} 

UPDATE2後我一些建議,而循環是所有情況下比的C-喜歡簡單的例子更復雜的最好替代通用for-loop(適用於表達式)。沒有必要每次都去尋找新的方法。
例如:與其

for var i = 0; i <= <array.count - 1; i++ 
{ 
    for var j = i + 1; j <= array.count - 1; j++ 
    { 
     //something with array[i] and array[j] 
    } 
} 

我可以使用

var i = 0 
while i < array.count 
{ 
    var j = i + 1 
    while j < array.count 
    { 
     //something with array[i] and array[j] 
     j += 1 
    } 
    i += 1 
} 
+0

是很重要的是他們這樣做成對?你在做什麼? – Fogmeister

+0

@Fogmeister我正在比較來自同一陣列的相鄰元素。 – VYT

+2

旁註:如果您使用「類似c」的循環,請考慮切換到我 Eiko

回答

1

最壞的情況,你可以將其轉換爲一個while循環。

var i = 0 
var j = 1 
while i <= array.count -2 && j <= array.count - 1 { 
    // something 
    i += 1 
    j += 1 
} 

- 編輯 -

因爲你說「而循環是所有情況下比的類C for循環的簡單的例子更復雜較好的通用替代」 ......我覺得需要擴大我的答案。我不想負責一堆糟糕的代碼...

在大多數情況下,有一個簡單的for-in循環,可以處理情況:

for item in array { 
     // do something with item 
    } 

    for (item1, item2) in zip(array, array[1 ..< array.count]) { 
     // do something with item1 and item2 
    } 

    for (index, item1) in array.enumerate() { 
     for item2 in array[index + 1 ..< array.count] { 
      // do soemthing with item1 and item2 
     } 
    } 

對於你最後的情況下, ,你可能有理由使用外觀,但這是一個極其罕見的邊緣情況。

不要亂扔for循環代碼。

+0

好的,謝謝!只是說一句。 Wile表達式看起來並不更短或更優雅,所以他們爲什麼決定放棄類似C的循環。 while表達式比for循環更有效嗎? – VYT

+0

如果你想知道*他們爲什麼*他們做到了。答案是可用的。 https://github.com/apple/swift-evolution/blob/master/proposals/0007-remove-c-style-for-loops.md –

+0

++我的風格也將被刪除:) – Darko

8

charl的(舊)答案會崩潰。你想0..<array.count

for index in 0..<array.count { 
    // ... 
} 

如果你想要的東西,就像你i/j循環中,您可以使用stride並獲得i的繼任者:

for i in 0.stride(through: array.count, by: 1) { 
    let j = i.successor() 
    // ... 
} 

只需確保檢查i.successor()的情況下,你出去的界限。

+0

如果我需要檢查兩個元素之間的一些元素 - 0和4,1和5 ....? – VYT

+0

@VYT將'for'循環從索引4開始,而不是爲'j'開始,並且將循環外部的索引'i'保持爲初始化爲0.在循環結束時,將'i'增加1.應該讓你比較'(0,4)','(1,5)',... – JAL

2

如果你想用隨後的對做點什麼,還有很多其他的方法可以做到。

像這樣的東西會工作...

var previousItem = array.first 

for index in 1..<array.count { 
    let currentItem = array[index] 

    // do something with current and previous items 

    previousItem = currentItem 
} 
2

待辦事項枚舉

let suits = ["♠︎", "♥︎", "♣︎", "♦︎"] 
for (i, suite) in suits.enumerate() { 
    // ... 
} 

或比較鄰居

import Foundation 

let suits = ["♠︎", "♥︎", "♣︎", "♦︎"] 
for (i, suite1) in suits.enumerate() { 
    let j = i.successor() 
    if j < suits.count { 
     let suite2 = suits[j] 
     // ... 
    } 
} 

或壓縮和枚舉

let suits = ["♠︎", "♥︎", "♣︎", "♦︎"] 
let combination = zip(suits, suits.dropFirst()) 
for (i, (s1,s2)) in combination.enumerate() { 
    print("\(i): \(s1) \(s2)") 
} 

結果

0: ♠︎ ♥︎ 
1: ♥︎ ♣︎ 
2: ♣︎ ♦︎ 
1

到相鄰元素來自同一陣列比較,你可以使用

let arr = [1,2,2,5,2,2,3,3] 
arr.reduce(nil) { (i, j)->Int? in 
    if let i = i { 
     print(i,"==",j,"is",i == j) 
    } 
    return j 
} 

它打印

1 == 2 is false 
2 == 2 is true 
2 == 5 is false 
5 == 2 is false 
2 == 2 is true 
2 == 3 is false 
3 == 3 is true 

更 '通用' 的方法,而無需使用下標,但單獨的發電機

let arr1 = [1,2,3,4,5,6,7,8,9,0] 

var g1 = arr1.generate() 
var g2 = (arr1.dropFirst(5) as AnySequence).generate() 
var g3 = (arr1.dropFirst(6) as AnySequence).generate() 

while true { 
    if let a1 = g1.next(), 
     let a2 = g2.next(), 
     let a3 = g3.next() { 
     print(a1,a2,a3) 
    } else { 
     break 
    } 
} 
/* prints 
1 6 7 
2 7 8 
3 8 9 
4 9 0 
*/ 
2
for (i, j) in zip(array.dropLast(), array.dropFirst()) 
{ 
    // something 
} 

你在做什麼真的這裏做的是枚舉兩個並行序列。因此,創建這些序列並使用zip將它們變成單個序列。

5
for var i = 0; i <= array.count - 1; i++ { 
     //something with array[i] 
} 

在這裏你不需要元素索引可言,所以你可以簡單地 枚舉數組元素:

for elem in array { 
    // Do something with elem ... 
} 

for var i = 0, j = 1; i <= array.count - 2 && j <= array.count - 1; i++, j++ { 
    //something with array[i] and array[j] 
} 

迭代a對的對djacent元件,使用zip()dropFirst()

for (x, y) in zip(array, array.dropFirst()) { 
    // Do something with x and y ... 
    print(x, y) 
} 

輸出:

 
1 2 
2 3 
3 4 
4 5 

對於其它的距離,應用dropFirst(n)

for (x, y) in zip(array, array.dropFirst(3)) { 
    // Do something with x and y ... 
    print(x, y) 
} 

輸出:

 
1 4 
2 5 

可能有許多解決方案,以做

for var i = 0; i <= <array.count - 1; i++ { 
    for var j = i + 1; j <= array.count - 1; j++ { 
     //something with array[i] and array[j] 
    } 
} 

沒有C風格的for循環,這裏是一個:

for (index, x) in array.enumerate() { 
    for y in array.dropFirst(index + 1) { 
     print(x, y) 
    } 
} 
+0

不錯,很清楚!如果起點不是數組中的第一個元素,即例如i等於3,那麼i = 3? – VYT

+0

@VYT:您可以將'.dropFirst(n)'應用於'zip()'表達式的兩個參數。 –

+0

啊,我試圖想辦法讓zip工作。 – Fogmeister