【问题标题】:Split and sort string array swift 3拆分和排序字符串数组swift 3
【发布时间】:2017-07-06 21:56:21
【问题描述】:

我正在寻找解决此问题的最有效方法。假设有一个对象数组,按名称按字母顺序排列:

let objectArray = [AnyObject]()
let abcNameObjectArray = ["Amy", "Bernadette", "Brian", "Chris", "Candice"]

如何根据 abcNameObject 数组中每个字符串值的第一个字符,按字母顺序访问此数组中具有“A”、“B”或“C”的所有值?我正在尝试卸载数据并根据一个可能按字母顺序排列的朋友的数量在 UITableView 的 cellForRowAt 方法和 numberOfRowsInSection 方法中返回特定数量的行。 目标是将数组拆分为一组数组,以填充表格视图,例如联系人应用程序,并且还可以访问给定部分的值。也许使用字典可能更好地解决这个问题?

【问题讨论】:

  • 如果它已经排序,那么你想做什么?为什么不遍历数组并创建一个字典数组,其中键为“A”,值作为成员数组?这里没有什么可排序的。只需按照找到它们的顺序继续在字典中的这个数组中添加元素。
  • 您需要edit您的问题,并根据您的输入获得所需的结果。不清楚你在这里期望什么。
  • 我需要将排序后的数组卸载到具有多个部分的 UITableView 中。会有一个 UITableView 有 26 个部分(字母表中的字母数),每个部分有 n 行...@rmaddy
  • @JoshuaChoi 正如我所说,edit 你的问题。不要让人们阅读所有的 cmets 来理解你的问题。

标签: arrays swift sorting


【解决方案1】:

解决方案 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": ["Bernadette", "Brian"], "a": ["Amy"], "c": ["Candice", "Chris"]]

解决方案 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)

输出:

[[“Amy”],[“Bernadette”,“Brian”],[“Chris”,“Candice”]]

您可以将节数作为此数组的计数,每个成员将给出该节所需的单元格数。

【讨论】:

  • 抱歉,我无法回复,但我认为您的解决方案是迄今为止最好的解决方案,因此我将其标记为答案。但是,有没有办法修改输出以返回对象数组,而不是字符串数组?
  • 感谢您的接受。是的,您可以退回任何东西。这只是一个例子。您可以如上所示修改reduce方法并使其返回对象数组。请随意尝试,如果您无法做到,请提出问题。我们可以帮助您。
【解决方案2】:

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 测试。

【讨论】:

    猜你喜欢
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    • 2014-02-18
    • 2018-05-26
    • 2019-12-13
    • 2014-10-29
    相关资源
    最近更新 更多