gpt4 book ai didi

ios - Swift:为名称列表创建部分索引

转载 作者:行者123 更新时间:2023-11-30 13:42:59 24 4
gpt4 key购买 nike

我编写了一个算法来为 TableView 创建节索引。不幸的是,当列表仅包含一项时,我遇到一个错误,结果为空。

你有一个优雅的解决方案吗?

var sections : [(index: Int, length :Int, title: String)] = Array()

func createSectionIndices(participants: List<Participant>){

sections.removeAll()

var index = 0;

let array = participants.sort({$0.lastName < $1.lastName})

for i in 0.stride(to: array.count, by: 1){

let commonPrefix = array[i].lastName.commonPrefixWithString(array[index].lastName, options: .CaseInsensitiveSearch)

if (commonPrefix.isEmpty) {

let string = array[index].lastName.uppercaseString;
let firstCharacter = string[string.startIndex]
let title = "\(firstCharacter)"
let newSection = (index: index, length: i - index, title: title)
sections.append(newSection)
index = i;
}
}
print("sectionCount: \(sections.count)")
}

最佳答案

这是构建部分列表的单行解决方案:

 var participants:[(firstName:String, lastName:String)] = 
[
("John", "Smith"),
("Paul", "smith"),
("Jane", "Doe"),
("John", "denver"),
("Leo", "Twain"),
("Jude", "law")
]

// case insensitive sort (will keep "denver" and "Doe" together)
participants = participants.sort({$0.lastName.uppercaseString < $1.lastName.uppercaseString})

// The process:
// - get first letter of each name (in uppercase)
// - combine with indices (enumerate)
// - only keep first occurrence of each letter (with corresponding indice)
// - build section tuples using index, letter and number of participants with name begining with letter
let sections = participants
.map({String($0.lastName.uppercaseString.characters.first!)})
.enumerate()
.filter({ $0 == 0 || !participants[$0 - 1].lastName.uppercaseString.hasPrefix($1) })
.map({ (start,letter) in return
(
index: start,
length: participants.filter({$0.lastName.uppercaseString.hasPrefix(letter)}).count,
title: letter
)
})

// sections will contain:
// (index:0, length:2, title:"D")
// (index:2, length:1, title:"L")
// (index:3, length:2, title:"S")
// (index:5, length:1, title:"T")

您可能已经有很多基于存储在元组数组中的部分的现有代码,但如果没有,我建议您采取稍微不同的方法,并使用字母和参与者数据构建您的部分数组。

 let sections = participants
.map({ String($0.lastName.uppercaseString.characters.first!) })
.reduce( Array<String>(), combine: { $0.contains($1) ? $0 : $0 + [$1] })
.map({ (letter) in return
(
title: letter,
participants: participants.filter({$0.lastName.uppercaseString.hasPrefix(letter)})
)
})

这将允许您使用sections.count响应部分的数量,但也将使操作每个部分中的索引路径和数据变得更容易:

  • 某个部分的参与者数量:sections[index].participants.count
  • 索引路径的参与者:sections[indexPath.section].participants[indexPath.row]

这只是语法上的糖果,但如果您有很多对参与者列表的引用,它将使代码更具可读性。
此外,如果您的参与者是对象而不是元组或结构,您甚至可以更新主参与者列表中的数据,而无需重建部分(除非更改了姓氏)。

[编辑]修复了最后一个元组语法中的错误

[编辑2] Swift 4 ...

Swift 4 中的字典提供了一种更简单的方法来管理此类事情。

原始引用结构:

 let sections = [Character:[Int]](grouping:participants.indices)
{participants[$0].lastName.uppercased().first!}
.map{(index:$1.reduce(participants.count,min), length:$1.count, title:String($0))}
.sorted{$0.title<$1.title}

.

对于包含自己的参与者子列表的部分结构(我的建议):

let sectionData = [Character:[Participant]](grouping:participants)
{$0.lastName.uppercased().first!}
.map{(title:$0, participants:$1)}
.sorted{$0.title<$1.title}

关于ios - Swift:为名称列表创建部分索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35343928/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com