按计算结果排序 NSFetchRequest

Posted

技术标签:

【中文标题】按计算结果排序 NSFetchRequest【英文标题】:Sort NSFetchRequest by calculation result 【发布时间】:2016-01-27 20:23:18 【问题描述】:

所以我有一个具有纬度和经度值的点数据集,我想检索它们并按到用户当前位置的距离对它们进行排序。目前,我有以下内容:

mainMoc.performBlockAndWait 
            // Fetching data from CoreData
            let fetchRequest = NSFetchRequest()
            fetchRequest.predicate = NSPredicate(format: "pointLatitude BETWEEN %f,%f AND pointLongitude BETWEEN %f,%f", (latitude-0.03), (latitude+0.03), (longitude-0.03), (longitude+0.03))
            let entity = NSEntityDescription.entityForName("PointPrimary", inManagedObjectContext: self.mainMoc)
            fetchRequest.entity = entity

            let sortDescriptor = NSSortDescriptor(key: "pointTitle", ascending: false)
            fetchRequest.sortDescriptors = [sortDescriptor]

            do 
                points = try self.mainMoc.executeFetchRequest(fetchRequest) as! [PointPrimary]

             catch 
                let jsonError = error as NSError
                NSLog("\(jsonError), \(jsonError.localizedDescription)")
                abort()
            
        

所以目前我只根据标题对其进行排序。但是,如果我想计算距离以说出 CLLocationCoordinate2D 并以此为基础对 fetchRequest 结果进行排序,我将如何进行?

非常感谢!

【问题讨论】:

【参考方案1】:

NSFetchRequest 不能使用模型中定义(并存储在数据库中)以外的属性作为排序描述符,因此您必须求助于内存排序。在您的 PointPrimary 类上定义一个 distance 方法,该方法执行适当的计算并执行以下操作:

let sortedPoints = points.sortedArrayUsingDescriptors([NSSortDescriptor(key: "distance", ascending: true)])

【讨论】:

【参考方案2】:

这应该可行。基本上你会使用带有自定义比较器的NSSortDescriptor

诀窍是使用"self" 作为NSSortDescriptor 的键,它将获取的对象传递给比较器。

var userLocation : CLLocation // get that from somewhere
var distanceCompare : NSComparator = 
    (obj1: AnyObject!, obj2: AnyObject!) -> NSComparisonResult in
    let lng1 = obj1.valueForKey("pointLongitude") as! CLLocationDegrees
    let lat1 = obj1.valueForKey("pointLatitude") as! CLLocationDegrees
    let p1Location : CLLocation = CLLocation(latitude: lat1, longitude: lng1)
    let p1DistanceToUserLocation = userLocation.distanceFromLocation(p1Location)

    let lng2 = obj2.valueForKey("pointLongitude") as! CLLocationDegrees
    let lat2 = obj2.valueForKey("pointLatitude") as! CLLocationDegrees
    let p2Location : CLLocation = CLLocation(latitude: lat1, longitude: lng1)
    let p2DistanceToUserLocation = userLocation.distanceFromLocation(p2Location)

    if (p1DistanceToUserLocation > p2DistanceToUserLocation) 
        return .OrderedDescending
     else if (p1DistanceToUserLocation < p2DistanceToUserLocation) 
        return .OrderedAscending
     else 
        return .OrderedSame
    


var distanceSortDescriptor = NSSortDescriptor(key: "self", ascending: true, comparator: distanceCompare)
fetchRequest.sortDescriptors = [distanceSortDescriptor]

【讨论】:

以上是关于按计算结果排序 NSFetchRequest的主要内容,如果未能解决你的问题,请参考以下文章

如何按距离从数据库中排序 php 结果

按对象方法的结果对 NSArray 进行排序

按价格排序列表,由列表内项目的子字符串计算#

Linq:按计算结果过滤并重用此结果

Linux TOP命令按内存占用排序和按CPU占用排序

按邮政编码距离升序计算和排序用户的最快方式(也是最优化的)