对数组进行排序以获得给定日期的最近日期

时间:2015-05-09 04:42:40

标签: ios objective-c sorting nsarray nsdate

数组包含如下字典。

NSArray *availableSlots = @[@{@"start" : <NSDate obj> , @"end" : <NSDate obj>},
                        @{@"start" : <NSDate obj> , @"end" : <NSDate obj>},
                        @{@"start" : <NSDate obj> , @"end" : <NSDate obj>},
                        @{@"start" : <NSDate obj> , @"end" : <NSDate obj>} ...];

我想让最近的开始和结束日期到选定的日期。

这是此解决方案的js伪代码功能。我想将其转换为Objective C。

function sortByProximityToPoint(a, b) {
        if (a.proximToPoint === undefined) {
            if (pointInTime.diff(a.start, 'minute') >= 0 &&
                pointInTime.diff(a.end, 'minute') <= 0) {
                a.proximToPoint = 0;
            } else if (pointInTime.diff(a.end, 'minute') > 0) {
                a.proximToPoint = Math.abs(pointInTime.diff(a.end, 'minute'));
            } else {
                a.proximToPoint = Math.abs(pointInTime.diff(a.start, 'minute'));
            }
        }

        if (b.proximToPoint === undefined) {
            if (pointInTime.diff(b.start, 'minute') >= 0 &&
                pointInTime.diff(b.end, 'minute') <= 0) {
                b.proximToPoint = 0;
            } else if (pointInTime.diff(b.end, 'minute') > 0) {
                b.proximToPoint = Math.abs(pointInTime.diff(b.end, 'minute'));
            } else {
                b.proximToPoint = Math.abs(pointInTime.diff(b.start, 'minute'));
            }
        }

        if (a.proximToPoint < b.proximToPoint) {
            return -1;
        }
        if (a.proximToPoint > b.proximToPoint) {
            return 1;
        }

        return 0;
    }

    availableSlots.sort(sortByProximityToPoint);

2 个答案:

答案 0 :(得分:1)

  

只是即使我能理解JavaScript pseudoCode,没有评论/解释,也需要更多的时间,用文字和例子来解释它有时更清楚。特别是对于那些可能遇到同样问题的人来说,如果这符合他/这里的问题,请快速查看。

所以你不明白算法的作用,并希望用英语而不是伪代码进行解释?

该函数是一个典型的比较函数,它返回三个值之一(-10+1)以指示其两个参数所在的顺序。您会看到此约定在许多语言中,Objective-C使用符号名称(NSOrderedAscending等)而不是数字(但在引擎盖下它们只是相同的三个数字)。

前两个部分产生一个适合于从每个提供的参数区间进行比较的数值。使用S表示间隔的开始时间,E结束时间,P与这些部分进行比较的时间点处理三种情况:

Time ->      P          S           E

P在开始时间之前:返回时差S - P。这是&#34;距离&#34; P来自区间。

Time ->      S          P           E

P在区间内:return 0

Time ->      S          E           P

P在结束时间之后:返回时差P - E。这是&#34;距离&#34; P来自区间。

现在算法有两个要比较的数字,意义较小&#34;更好&#34;,这意味着排序更早。因此,它比较两个数字并返回指示顺序的适当值。

在Objective-C中,您将使用块而不是函数,将其直接传递给NSArray的相应排序方法。日期时间比较和差异函数来自NSDate

虽然你可以实现&#34; proxim&#34;的Javascript缓存的等价物。值(伪代码中的undefined内容)你应该留下它,直到你觉得它是必要的。只需使用local(到块)变量。

另请注意,绝对值功能的使用是不必要的 - 请考虑一下。

HTH

答案 1 :(得分:-1)

// sort them
NSArray *sortedArray = [availableSlots sortedArrayUsingComparator:^NSComparisonResult(NSMutableDictionary* a, NSMutableDictionary* b) {

    if (a[@"proximToPoint"] == [NSNull null]) {
        if ([(NSDate *)a[@"start"] compare:time] != NSOrderedDescending && [(NSDate *)a[@"end"] compare:time] != NSOrderedAscending) {
            [a setObject:@0 forKey:@"proximToPoint"];
        } else if ([(NSDate *)a[@"end"] compare:time] == NSOrderedAscending){
            [a setObject:@(abs([(NSDate *)a[@"end"] compare:time])) forKey:@"proximToPoint"];
        } else {
            [a setObject:@(abs([(NSDate *)a[@"start"] compare:time])) forKey:@"proximToPoint"];
        }
    }

    if (b[@"proximToPoint"] == [NSNull null]) {
        if ([(NSDate *)b[@"start"] compare:time] != NSOrderedDescending && [(NSDate *)b[@"end"] compare:time] != NSOrderedAscending) {
            [b setObject:@0 forKey:@"proximToPoint"];
        } else if ([(NSDate *)b[@"end"] compare:time] == NSOrderedAscending){
            [b setObject:@(abs([(NSDate *)b[@"end"] compare:time])) forKey:@"proximToPoint"];
        } else {
            [b setObject:@(abs([(NSDate *)b[@"start"] compare:time])) forKey:@"proximToPoint"];
        }
    }

    if (a[@"proximToPoint"] > b[@"proximToPoint"]) {
        return (NSComparisonResult)NSOrderedDescending;
    }

    if (a[@"proximToPoint"] < b[@"proximToPoint"]) {
        return (NSComparisonResult)NSOrderedAscending;
    }

    return (NSComparisonResult)NSOrderedSame;
}];