Arrays 为什么';我的数组不是从映射到它的第一个项开始的吗?敏捷的
我正在编写一个应用程序,使用Swift显示和浏览一系列问题和答案。我目前有一个问题和相关答案的字典,然后使用.map创建一个“flashcard”对象数组(每个对象包含一个问题及其相关答案) 然后,当我从数组中访问这些对象时,由于某种原因,返回的第0项似乎是字典中的第二项,而不是第一项(例如“问题2”)。有人能解释为什么会这样吗?该类创建数据数组,并提供将项目返回到相关视图控制器的方法:Arrays 为什么';我的数组不是从映射到它的第一个项开始的吗?敏捷的,arrays,swift,dictionary,Arrays,Swift,Dictionary,我正在编写一个应用程序,使用Swift显示和浏览一系列问题和答案。我目前有一个问题和相关答案的字典,然后使用.map创建一个“flashcard”对象数组(每个对象包含一个问题及其相关答案) 然后,当我从数组中访问这些对象时,由于某种原因,返回的第0项似乎是字典中的第二项,而不是第一项(例如“问题2”)。有人能解释为什么会这样吗?该类创建数据数组,并提供将项目返回到相关视图控制器的方法: import Foundation class Deck { // Create cons
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]
}
}
然后这是我的视图控制器,我请求在其中显示对象:
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”…问题是
字典中键值对的顺序未指定–它完全取决于实现,并且不能保证与用于创建字典的字典文本中键值对的显示顺序相同
在您的案例中,一个简单的解决方案是使用,而不是字典,而是一个–它维护键值对的顺序:
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
}
这是因为,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
}
- 它有一个从零开始的
Int
索引,您可以用它下标
- 它不要求密钥是可散列的
因此,它的主要用途实际上只是一点暂时的语法糖分(允许使用字典文字)在您将键值对打包到实际数据结构中之前–我们在这里使用它的方式。问题是
字典中键值对的顺序未指定–它完全依赖于实现,并且不能保证与用于创建字典的字典文本中键值对的显示顺序相同
在您的案例中,一个简单的解决方案是使用,而不是字典,而是一个–它维护键值对的顺序:
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
}
这是因为,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
}
- 它有一个从零开始的
Int
索引,您可以用它下标
- 它不要求密钥是可散列的
因此,在将键值对打包到实际数据结构中之前,它的主要用途实际上只是一点暂时的语法糖分(允许使用字典文本),这正是我们在这里使用它的方式。Related:.Related:.谢谢Hamish,我想知道这是否与此有关,但我在想,也许每次运行应用程序时,它都会随机从不同的对象开始,而它总是从第二项开始。@laurie Happy help:)值得注意的是,在执行需要依赖相同的程序–因为
Hashable
协议不能保证在不同执行过程中为同一实例返回的哈希值是稳定的(这在文档中有特别说明)。Hello@Hamish,您认为自定义模型数组会更好吗?顺便说一句,最后我看到了DictionaryLiteral
的一个有用用法,谢谢你的回答。@AhmadF一个自定义模型数组正是OP在本例中所做的(一个[Flashcard]
)–这里使用DictionaryLiteral
实际上只是为了语法上的方便,这样OP就不必写出一个数组“Flashcard(问题:…,答案:…)
“对于每个元素。相反,我们只需陈述问题和答案字符串对。谢谢Hamish,我想知道这是否与此有关,但我在想,也许每次运行应用程序时,它都会随机从不同的对象开始,而它总是从第二项开始。@laurie Happy help:)值得注意的是,在执行需要依赖相同的程序–因为Hashable
协议不能保证在不同执行过程中为同一实例返回的哈希值是稳定的(这在文档中有特别说明)。Hello@Hamish,您认为自定义模型数组会更好吗?顺便说一句,最后我看到了DictionaryLiteral
的一个有用用法,谢谢你的回答。@AhmadF一个自定义模型数组正是OP在本例中所做的(一个[Flashcard]
)–这里使用DictionaryLiteral
实际上只是为了语法上的方便,这样OP就不必写出一个数组“Flashcard(问题:…,答案:…)
”用于每个元素。我们只需声明问题和答案字符串对。