2015-05-09 3 views
0

Массив содержит словари, как показано ниже.Сортировка массива для получения ближайших дат к заданной дате

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 Pseudocode для этого решения. Я хочу, чтобы преобразовать его в 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); 
+1

'NSDate' предоставляет методы для сравнения и различия, и есть функция абс в (C) объективно-то, что именно вы испытываете проблемы? – CRD

+0

Я хочу получить ближайшие доступные слоты для pointInTime (выбранная дата). –

+0

Понял, и у вас даже есть код для этого. При переходе на Objective-C, где вы застряли? (Вы можете отредактировать вопрос, чтобы показать это.) – CRD

ответ

1

Это просто, что даже если я могу понять JavaScript псевдокод, без комментариев/объяснений, это занимает больше времени, иногда понятнее объясняет словами и примерами. Специально для тех, у кого может быть такая же проблема, быстро увидеть, если это соответствует его/здесь проблеме.

Итак, вы не понимаете, что алгоритм делает и хотел бы объяснить на английском языке, а не псевдокод?

Функция является типичной функцией сравнения, которая возвращает одно из трех значений (-1, 0, +1), чтобы указать порядок ее два аргумента. Вы видите это соглашение на многих языках, Objective-C использует символические имена (NSOrderedAscending и т. д.), а не числа (но под капотом они являются одинаковыми тремя числами).

Первые две секции производят числовое значение, подходящее для сравнения с каждым из предоставленных интервалов аргументов. Использование S означает время начала интервала, E конечное время, и P момент времени сравниваемых против этих секций обрабатывать три случая:

Time ->  P   S   E 

P есть до времени начала: вернуть разницу во времени S - P. Это «расстояние» P от интервала.

Time ->  S   P   E 

P находится в интервале: возвращение 0

Time ->  S   E   P 

P есть после окончания времени: вернуть разницу во времени P - E. Это «расстояние» P от интервала.

Теперь алгоритм имеет два числа для сравнения, с меньшим значением «лучше», что означает, что раньше это происходит раньше. Поэтому он сравнивает два числа и возвращает соответствующее значение, указывающее порядок.

В Objective-C вы должны использовать блок вместо функции, передавая его непосредственно соответствующему методу сортировки NSArray. Функции сравнения даты и времени с датой и временем относятся к NSDate.

Хотя вы могли бы реализовать эквивалент кеширования Javascript значений «proxim» (undefined в псевдокоде), вы должны оставить это до тех пор, пока не найдете нужным. Просто используйте локальные (для блока) переменные.

Обратите также внимание на то, что использование функции абсолютного значения не требуется - подумайте об этом.

НТН

+0

Это хорошее объяснение CRD. Наконец-то мне удалось найти код Obj-c. Надеюсь, мой ответ тоже поможет кому-то –

-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; 
}]; 
+0

Извините, но этот ответ не реализует алгоритм, и он также не работает. Значение 'proximToPoint' всегда либо' 0' (точка в слоте), либо '1' (точка вне слота). Прочтите мое объяснение алгоритма снова. Вы также эмулируете способность Javascript динамически добавлять свойства, требуя, чтобы все элементы, которые были отсортированы, являются изменяемыми словарями * и * имеют ключ 'proximToPoint' со значением' [NSNull null] 'до начала сортировки. В вашем ответе не содержится кода для этого; вам не нужно делать это кеширование, но если вы это сделаете, можете ли вы не думать о лучшем пути? – CRD

Смежные вопросы