swift 中的 index(where:) 方法生成了错误的索引

index(where:) method in swift is producing the wrong index

我收到数组索引超出范围错误。我有两个数组 cardsCurrentlyInPlaycurrentCardsSelected。这个游戏中的每张卡都有一个唯一的 ID。我试图在 cardsCurrentlyInPlay 中找到卡片的索引,其 cardIDcurrentCardsSelected 中卡片的 cardID 匹配。我通过使用需要闭包的 index(where:) 方法来做到这一点。我的闭包只是检查 ID 是否匹配,它们显然匹配,因为我正在使用 ! 来解包它们并且应用程序不会在那里崩溃。 index(where:) 方法似乎返回了错误的索引。我已经看了好几个小时了,但我不明白发生了什么。

代码如下:

    let indexOfFirstCard = cardsCurrentlyInPlay.index(where: ({([=11=]?.cardID == currentCardsSelected[0].cardID)}))!
    let indexOfSecondCard = cardsCurrentlyInPlay.index(where: ({([=11=]?.cardID == currentCardsSelected[1].cardID)}))!
    let indexOfThirdCard = cardsCurrentlyInPlay.index(where: ({([=11=]?.cardID == currentCardsSelected[2].cardID)}))!

    if deck.isEmpty && selectedCardsMakeASet() {

        /* Remove the old cards */
        cardsCurrentlyInPlay.remove(at: indexOfFirstCard)
        cardsCurrentlyInPlay.remove(at: indexOfSecondCard)
        cardsCurrentlyInPlay.remove(at: indexOfThirdCard) // where code is blowing up

        currentCardsSelected.removeAll()

        /* Return indicies of cards to clear from the UI */
        return .deckIsEmpty(indexOfFirstCard, indexOfSecondCard, indexOfThirdCard)

    }

你得到的索引在你得到它时是正确的,但是当你移除其他卡片时它变得错误。考虑:

var a = ["x", "y", "z"]
let indexOfX = a.index(of: "x")!  // returns 0
let indexOfZ = a.index(of: "z")!  // returns 2
a.remove(at: indexOfX)  // removes "x"; now a = ["y", "z"]
a.remove(at: indexOfZ)  // index 2 is now out of bounds

您可以交替调用 index(of:)remove(at:),但更好的方法是一次删除所有三张卡片,如下所示:

let selectedCardIDs = currentCardsSelected.map { [=11=].cardID }
cardsCurrentlyInPlay = cardsCurrentlyInPlay.filter { card in
    !selectedCardIDs.contains(card.cardID)
}

请注意,这具有避免强制展开的额外好处,这是更合理逻辑的标志。

这是因为越界

前两段代码执行后。 cardsCurrentlyInPlay.remove(at: indexOfFirstCard) & cardsCurrentlyInPlay.remove(at: indexOfSecondCard) cardsCurrentlyInPlay 中只有一个元素。 那么如果你执行cardsCurrentlyInPlay.remove(at: indexOfThirdCard),程序就会崩溃