我正在使用CoreData和Swift 3,但我认为这更像是关于NSPredicates,NSSortDescriptors和NSFetchedResultsController的一般性问题......
我有一个具有整数属性的实体,我想要排序,但我需要根据传入的整数拆分结果,并按降序独立排序两半,然后将它们组合起来。具有属性< =分裂值的所有实体都在前面(下降),并且所有实体都是>分裂值在末尾(降序)。
以下是一个例子:
正常获取的结果按整数属性按降序排序:
[10,9,8,7,6,5,4,3,2,1]
给定" 5"的分割值,最终结果应为:
[5,4,3,2,1,10,9,8,7,6]
或者分割值为8,最终结果应为:
[8,7,6,5,4,3,2,1,10,9]
我正在做的是创建一个翻转点,一个月的天数在28,29,30或31处滚动。在我的情况下,翻转点是动态的,我不在使用天。
我无法弄清楚如何使用谓词和排序描述符来完成此操作。这甚至可能吗?
我已经阅读了有关使用" sortOrder"进行多次抓取的内容。实体中的属性。基本上,取一次,将结果放入数组,按照我想要的方式对数组进行排序,然后设置" sortOrder"每个实体上的属性,保存上下文,然后再次获取,按" sortOrder"排序。我可以做到,但我希望有更优雅的东西。
这里有一些代码可以对数组进行正确的排序:
func rolloverSort(withArray: [Int], andIndex index: Int) -> [Int] {
let inputArray = withArray.sorted()
var newArray = [Int]()
var splitIndex: Int = 0
for item in inputArray {
if item <= index {
newArray.insert(item, at: 0)
splitIndex += 1
}
if item > index {
newArray.insert(item, at: splitIndex)
}
}
return newArray
}
结果将驱动UITableView,所以我需要在NSFetchedResultContoller的上下文中执行此操作,这就是我考虑谓词和排序描述符的原因。
这是我的NSFetchedResultsController和一些周围的上下文:
// sortMethod (used in sortDescriptor) is set via an action sheet button.
// Currently it's just a string for the entity attribute to sort on.
// The closure on each button sets self._fetchedRequestController = nil,
// sets sortMethod to the desired sorting string, then calls
// tableView.reloadData().
var fetchedResultsController: NSFetchedResultsController<Entity> {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest: NSFetchRequest<Entity> = Entity.fetchRequest()
fetchRequest.fetchBatchSize = 20
let sortDescriptor = NSSortDescriptor(key: sortMethod, ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
let aFetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: managedObjectContext!,
sectionNameKeyPath: nil,
cacheName: "Master")
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController
do {
try _fetchedResultsController!.performFetch()
} catch {
// FIXME: Replace error handling stub.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController<Card>? = nil
这适用于简单的排序,但我正在努力弄清楚如何从A.Jam中插入排序功能。
答案 0 :(得分:1)
假设您有一个数据存储,其中已插入了10个名为Number
的实体。模型实体有一个名为value
的属性Int32
,您要对其进行排序(数据存储中的值范围为1到10)。
使用此功能可根据键值拆分数据,并使用NSSortDescriptor
的实例对其进行排序:
func fetchSortEntites(basedOn integer: Int32) -> ([Int32], [Number]){
var sortedNumberArray: [Int32] = []
var sortedManagedObjects: [Number] = []
// Phase 1
let predicate1 = NSCompoundPredicate(format: "value <= %ld", integer)
let sortDescriptor1 = NSSortDescriptor(key: "value", ascending: false)
let fetchRequest1 = NSFetchRequest<Number>(entityName: "Number")
fetchRequest1.predicate = predicate1
fetchRequest1.sortDescriptors = [sortDescriptor1]
do{
let managedObjects = try managedObjectContext.fetch(fetchRequest1)
for managedObject in managedObjects{
sortedNumberArray.append(managedObject.value)
sortedManagedObjects.append(managedObject)
}
} catch let error as NSError {
print(error.debugDescription)
fatalError("*** Failed to fetch managed objects from the context!")
}
// Phase 2
let predicate2 = NSCompoundPredicate(format: "value > %ld", integer)
let sortDescriptor2 = NSSortDescriptor(key: "value", ascending: false)
let fetchRequest2 = NSFetchRequest<Number>(entityName: "Number")
fetchRequest2.predicate = predicate2
fetchRequest2.sortDescriptors = [sortDescriptor2]
do{
let managedObjects = try managedObjectContext.fetch(fetchRequest2)
for managedObject in managedObjects{
sortedNumberArray.append(managedObject.value)
sortedManagedObjects.append(managedObject)
}
} catch let error as NSError {
print(error.debugDescription)
fatalError("*** Failed to fetch managed objects from the context!")
}
return (sortedNumberArray, sortedManagedObjects)
}
}
结果:
let myTuple = fetchSortEntites(basedOn: 5)
for number in myTuple.0{
print (number)
}
let myTuple = fetchSortEntites(basedOn: 8)
for number in myTuple.0{
print (number)
}
希望这有帮助!
答案 1 :(得分:0)
您可以围绕两个NSFetchedResultsController创建包装器(下一个 resultsController )。
第一个resultsController应该在(&lt; =)阈值之前获取值,第二个resultsController应该在(&gt;)阈值之后获取值。
之后,包装器可以将所需数据作为来自requestControllers的数据联合返回
例如:
//Get count cells
int countCells = resultsController1.sections.first.numberOfObjects + resultsController2.sections.first.numberOfObjects;
<...>
//Get value for cell
int value = 0;
if (cellIndex >= <counts_in_first_resultsController>)
{
value = <Get_from_the_second>;
}
else
{
value = <Get_from_the_first>;
}