2016-09-29 61 views
4

我有一個Bools數組,並且想要編輯一個數組的數組和一個False數組的日期。我無法做到。我想要獲取錯誤的元素,並使用該數組從元數組中刪除這些元素,但我可以想象有一種直接的方法。Swift根據另一個Bool數組篩選其他數組

let hbiCompleteArray = [true, true, true, true, false, true, true, false, false] 

let hbiScoreArray = [12, 12, 12, 12, 3, 13, 13, 2, 2] 

我想completeHbiScores =的陣列[12,12,12,12,13,13]

+3

考慮使用** **中之一的模型,而不是多個陣列的自定義結構的陣列。 – vadian

+0

OOO聽起來超酷,我該怎麼做? – SashaZ

+0

[Swift語言指南:類和結構](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html) – vadian

回答

5

如果必須使用兩個陣列,可以用zipfilter和解決這個map這樣的:

let hbiCompleteArray = [true, true, true, true, false, true, true, false, false] 
let hbiScoreArray = [12, 12, 12, 12, 3, 13, 13, 2, 2] 

let result = zip(hbiCompleteArray, hbiScoreArray).filter { $0.0 }.map { $1 } 
print(result) 

給出:

[12,12,12,12,13,13]

說明:zip交織兩個陣列(使得(Bool, Int)元組的陣列),那麼filter { $0.0 }僅保持true布爾值,則map只保留Int值。

+0

這是一個很好且相當簡單的方法陣列不會太大。唯一的問題是每個這些操作都會遍歷數組,所以它可能會在大型數組上陷入困境。優化足夠了嗎?這取決於你自己決定,當然不要求更復雜的解決方案,除非測試顯示這對你的需求來說太慢了。 – ColGraff

+0

以前從未見過'zip'! – Honey

+0

@Honey它創建一個[Zip2Sequence](http://sketchytech.blogspot.co.uk/2016/03/swift-sticking-together-with.html)實例。 – sketchyTech

1

同意平行陣列的方法是不是最好的結構,使用你的代碼,但過濾和映射使用由Eric另一種是降低:

let completeHbiScores = zip(hbiCompleteArray, hbiScoreArray).reduce([Int]()){ 
    (newArray,zippedArray) in 
    if zippedArray.0 { 
     return newArray + [zippedArray.1] 
    } 
    else { 
     return newArray 
    }} 
4

從vadian的評論在這裏非常重要。你不應該有這樣的多個數組。創建一個包含數據的結構:

struct Score { 
    let isComplete: Bool 
    let finalScore: Int 
} 

然後,您可以添加Date或任何其他您當前具有並行陣列的字段。然後你的數據是這樣的:

let scores = [ 
    Score(isComplete: true, finalScore: 12), 
    Score(isComplete: true, finalScore: 12), 
    Score(isComplete: true, finalScore: 12), 
    Score(isComplete: true, finalScore: 12), 
    Score(isComplete: false, finalScore: 3), 
    Score(isComplete: true, finalScore: 13), 
    Score(isComplete: true, finalScore: 13), 
    Score(isComplete: false, finalScore: 2), 
    Score(isComplete: false, finalScore: 2), 
] 

並獲得完整的人是通過過濾

let completeScores = scores.filter { $0.isComplete } 

當然,如果你想只是最後得分爲數組簡單,你可以向下映射到:

let finalCompleteScores = completeScores.map { $0.finalScore } 

這就是你應該如何考慮你的數據,而不是你必須保持同步的一堆數組。

+1

如果您可以將數據放入單個結構中,這當然是最佳解決方案,它通常會導致更簡潔,更易於維護的代碼。如果由於其他設計原因必須有兩個陣列,那麼其他解決方案可能會更好。 – ColGraff

+0

我喜歡這個解決方案,因爲我也可以添加分數的日期。然後我可以使用圖表的日期/分數。我會在稍後嘗試。 – SashaZ

0

另一個相當容易的方式來做到這一點,通過你的陣列迭代只有一次是這樣的:

let hbiCompleteArray = [true, true, true, true, false, true, true, false, false] 
let hbiScoreArray = [12, 12, 12, 12, 3, 13, 13, 2, 2] 
var completeHbiScores = [Int]() 

for score in hbiScoreArray.enumerated() { 
    // break out of the loop if we're at the end of hbiCompleteArray 
    // assuming that no value means default to false 
    guard score.offset < hbiCompleteArray.count else { break } 

    // go to the next score if the current element is false 
    guard hbiCompleteArray[score.offset] else { continue } 

    completeHbiScores.append(score.element) 
}