我正在尝试在一个结构中创建一个变异函数,该函数将按其 String 属性对数组进行排序。这样,无论何时将一个项目添加到数组中,它都会按字母顺序对自身进行排序。我意识到我现在所拥有的试图在自己数组的 didSet 方法中对数组进行更改,但我不确定现在该去哪里。目前我收到错误“Thread 1: EXC_BAD_ACCESS (code=2, address=...)”。在尝试实现排序方法之前,所有其他代码都运行良好。
import Foundation
struct QuoteLibrary {
var title : String
var arrayOfSectionTitles: [String]
var arrayOfSections : [Section] = [] {
didSet {
self.configureSections()
}
}
mutating func configureSections() {
// Sort alphabetically
arrayOfSections.sort({ $0.title > $1.title })
let numberOfSections = arrayOfSections.count - 1
// Update the arrayOfSectionTitles whenever arrayOfSections is set
var titleArray: [String] = []
for k in 0...numberOfSections {
titleArray.append(arrayOfSections[k].title)
}
arrayOfSectionTitles = titleArray
// If a section has no quotes in it, it is removed
for j in 0...numberOfSections {
if arrayOfSections[j].arrayOfQuotes.count == 0 {
arrayOfSections.removeAtIndex(j)
return
}
}
}
}
struct Section {
var title : String, arrayOfQuotes:[Quote]
}
struct Quote {
var section : String, text : String
}
enum QuoteStatus: Int {
case Unchanged = 0
case Changed = 1
case Deleted = 2
case Added = 3
}
最佳答案
你有一个递归问题。每次您触摸 arrayOfSections
时,它都会调用 configureSections
。 包括 configureSections
对arrayOfSections
所做的更改,例如排序或删除空部分。您可能只是通过删除空部分来摆脱它(因为在删除之后,后续调用不会删除任何内容,因此不会更改数组并重新调用该函数),但是对其进行排序会将事情覆盖边缘。
你可能最好使用一个私有(private)数组,然后是一个提供对它的访问的计算属性,如下所示:
struct QuoteLibrary {
private var _arrayOfSections: [Section] = []
var title: String
var arrayOfSectionTitles: [String] = []
var arrayOfSections: [Section] {
get { return _arrayOfSections }
set(newArray) {
_arrayOfSections = newArray.filter { !$0.arrayOfQuotes.isEmpty }
_arrayOfSections.sort { $0.title > $1.title }
arrayOfSectionTitles = _arrayOfSections.map { $0.title }
}
}
init(title: String) { self.title = title }
}
此外,您肯定想了解 Swift 的映射、数组过滤等功能,作为 for 循环的替代方案。尤其是对于您的删除循环 - 在迭代数组时从数组中删除元素确实非常棘手,filter
更不容易出错。
关于arrays - 如何按属性类型自动排序 Swift 中的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27714529/