arrays - 为什么我的数组不从映射到它的第一个项目开始? swift

标签 arrays swift dictionary

我正在编写一个应用程序,以使用 Swift 显示和浏览一系列问题和答案。我目前有一个问题和相关答案的字典,然后我通过使用 .map 创建一个“抽认卡”对象数组(每个对象都有一个问题及其相关答案)。

然后当我从数组中访问这些对象时,出于某种原因,返回的第 0 个项目似乎是我字典中的第二个项目而不是第一个(例如“问题 2”)。有人可以解释这是为什么吗?这是创建数据数组并提供将项目返回到相关 View Controller 的方法的类:

    import Foundation

class Deck {
    // Create constant to hold the deck of cards
    private var cards: [Flashcard]
    var bookmark: Int // Remembers which card we are on


    init() {
        let cardData = ["Question 1" : "Answer 1",
                        "Question 2" : "Answer 2",
                        "Question 3" : "Answer 3"]

        cards = cardData.map { Flashcard(question: $0, answer: $1) }
        bookmark = 0 // Start with bookmark on first item in deck
    }

    // Getter method to return current card
    public func getCurrentCard() -> Flashcard {
        print("Bookmark set to \(bookmark)")
        return cards[bookmark]
    }

    // Getter method to return the next card in the deck
    public func getNextCard() -> Flashcard {
        bookmark += 1
        print("Bookmark set to \(bookmark)")
        return cards[bookmark]
    }

    // Getter method to return previous card in deck
    public func getLastCard() -> Flashcard {
        bookmark -= 1
        print("Bookmark set to \(bookmark)")
        return cards[bookmark]
    }
}

然后这是我的 View Controller ,我请求在其中显示对象:

import UIKit

class QuestionController: UIViewController {

  // Outlet for the 'question' label
    @IBOutlet weak var questionTextView: UITextView!

    // Outlet for the next button
    @IBAction func nextQuestion(_ sender: UIButton) {
        flashcard = deck.getNextCard()
        questionTextView.text = flashcard?.question

    }

    // Outlet for last button
    @IBAction func lastQuestion(_ sender: UIButton) {
        flashcard = deck.getLastCard()
        questionTextView.text = flashcard?.question
    }



    // variable to hold current flashcard
    var flashcard: Flashcard?
    let deck = Deck() // Holds deck of data

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        flashcard = deck.getCurrentCard()
        questionTextView.text = flashcard?.question

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }



// Prepare flashcard item to be passed to the answer controller before segue
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let answerController = segue.destination as? AnswerController {
            answerController.flashcard = flashcard
        }
    }

}

当我运行该应用程序时,显示的第一个问题是“问题 2”,而我期望它是“问题 1”...?

最佳答案

问题是 Dictionary 中键值对的顺序是未指定——它完全依赖于实现,并不保证与字典中的顺序相同其中键值对出现在您用来创建字典的字典文字中。

针对您的情况,一个简单的解决方案是不使用字典,而是使用 DictionaryLiteral。 – 维护键值对的顺序:

init() {
    let cardData: DictionaryLiteral = ["Question 1" : "Answer 1",
                                       "Question 2" : "Answer 2",
                                       "Question 3" : "Answer 3"]

    cards = cardData.map { Flashcard(question: $0, answer: $1) }
    bookmark = 0 // Start with bookmark on first item in deck
}

这是因为under the hood , DictionaryLiteral 只不过是一个键值元组数组。正因为如此,您会注意到它的行为与 Dictionary 在这方面有很大不同,并且保持键值对的顺序:

  • 它有一个从零开始的 Int 索引,您可以用它来下标
  • 它不要求键是Hashable
  • 它允许重复键
  • key 查找发生在线性(非常数)时间内

因此,它的主要用途实际上只是一点短暂的语法糖(允许使用字典文字),然后再将键值对打包到您的实际数据结构中——这正是我们在这里使用它的方式。

关于arrays - 为什么我的数组不从映射到它的第一个项目开始? swift ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43963409/

相关文章:

javascript - JavaScript 引擎如何将数组对象的类型更改为字符串

ios - 从 Objective C 代码调用 @escaping 完成处理程序时出现 EXC_BAD_ACCESS 错误

dictionary - 在 Dart 中减少/过滤 map 的首选方法?

python - 将一维 NumPy 数组作为列插入现有二维数组中

javascript - 用于多个选择选项下拉列表的本地存储

javascript - Node, Javascript 中的算法优化

swift - 在 swift 中设置 cornerRadius 时是否需要调用方法 "awakeFromNib()"?

ios - 如何在另一个 View Controller Swift 4 中将数据插入 TableView?

swift - 无法减去包含两个字典的两个集合

c# - 灵活使用 IDictionary(带接口(interface))