2016-09-29 86 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) 
} 
相关问题