我正在寻找最有效的方法来解决这个问题。假设有一个对象数组,按名称按字母顺序映射:
let objectArray = [AnyObject]()
let abcNameObjectArray = ["Amy", "Bernadette", "Brian", "Chris", "Candice"]
如何根据 abcNameObject 数组中每个字符串值的第一个字符(按字母顺序排列)访问此数组中具有“A”、“B”或“C”的所有值?我正在尝试卸载数据,并根据按字母顺序排列的朋友数量,在 UITableView 的 cellForRowAt 方法和 numberOfRowsInSection 方法中返回特定数量的行。 目标是将数组拆分为一组数组,以填充表视图(如联系人应用程序),并访问给定部分的值。也许利用字典可能会更好地解决这个问题?
解决方案1:
用代码发布我的评论作为答案。检查这是否适合您。您可以使用下面打印的第一个数组中的部分(将
dict.keys.sorted()
存储到某个数组中)并将其用作显示该部分中的单元格的键。
let abcNameObjectArray = ["Amy", "Bernadette", "Brian", "Chris", "Candice", ""]
let dict = abcNameObjectArray.reduce([String: [String]]()) { (key, value) -> [String: [String]] in
var key = key
if let first = value.characters.first {
let prefix = String(describing: first).lowercased()
var array = key[prefix]
if array == nil {
array = []
}
array!.append(value)
key[prefix] = array!.sorted()
}
return key
}
print(dict.keys.sorted())
print(dict)
输出:
[“a”,“b”,“c”]
[“b”:[“伯纳黛特”,“布莱恩”],“a”:[“艾米”],“c”:[“坎迪斯”,“克里斯”]]
解决方案2:
这是 rmaddy 建议的使用数组数组的另一种解决方案
let abcNameObjectArray = ["Amy", "Bernadette", "Brian", "Chris", "Candice", ""]
let unicodeScalarA = UnicodeScalar("a")!
var arrayOfArrays = abcNameObjectArray.reduce([[String]]()) { (output, value) -> [[String]] in
var output = output
if output.count < 26 {
output = (1..<27).map{ _ in return []}
}
if let first = value.characters.first {
let prefix = String(describing: first).lowercased()
let prefixIndex = Int(UnicodeScalar(prefix)!.value - unicodeScalarA.value)
var array = output[prefixIndex]
array.append(value)
output[prefixIndex] = array.sorted()
}
return output
}
arrayOfArrays = arrayOfArrays.filter { $0.count > 0}
print(arrayOfArrays)
输出:
[[“艾米”]、[“伯纳黛特”、“布莱恩”]、[“克里斯”、“坎迪斯”]]
您可以将部分数量作为该数组的计数,每个成员将给出该部分所需的单元格数量。
A
Set
对于表视图的数据源来说不是一个好的选择。 Dictionary
也不是一个好的选择。两者都是无序集合,表视图的数据源需要有明确的顺序。我建议将源数组分解为数组数组,其中每个子数组包含以特定字母开头的所有单词,并按字母顺序排序。代码可能如下所示:
import UIKit
let strings = ["arf",
"woofing",
"flounder",
"Manbaby",
"Dogs",
"baseballs",
"Suet",
"Cards",
"Tiny-fingered, cheeto-faced, ferret-wearing sh*tgibbon",
"apple",
"Acorn",
"Achy-breaky heart",
"songbirds",
"Aces"]
let aValue = "a".unicodeScalars.first!.value
let zValue = "z".unicodeScalars.first!.value
var result = [[String]]()
for value in aValue...zValue {
let aChar = Character(UnicodeScalar(value)!)
let thisArray = strings
.filter{$0.lowercased().characters.first! == aChar}
.sorted{$0.caseInsensitiveCompare($1) == .orderedAscending}
if !thisArray.isEmpty {
result.append(thisArray)
}
}
result.forEach{print($0)}
产生以下输出:
["Aces", "Achy-breaky heart", "Acorn", "apple", "arf"]
["baseballs"]
["Cards"]
["Dogs"]
["flounder"]
["Manbaby"]
["songbirds", "Suet"]
["Tiny-fingered, cheeto-faced, ferret-wearing sh*tgibbon"]
["woofing"]
如果您想要一个包含每个字母的条目的数组,即使没有以该字母开头的单词,也请摆脱
if !thisArray.isEmpty
测试。