Как сравнить NSDates, чтобы найти самые ранние и самые поздние даты в массиве? - PullRequest
4 голосов
/ 12 января 2012

У меня много проблем с моим кодом, который определяет самую раннюю дату и самую позднюю дату в массиве. Вот код, который я использую:

NSDate *startDate = nil; // Earliest date
NSDate *endDate = nil; // Latest date

for (id entry in myArray) 
{
    NSDate *date = [entry objectForKey:kDate];

    if (startDate == nil && endDate == nil) 
    {
        startDate = date;
        endDate = date;
    }
    else if ([date compare:endDate] == NSOrderedAscending)
    {
        startDate = date;
    }
    else if ([date compare:startDate] == NSOrderedDescending)
    {
        endDate = date;
    }

    date = nil;
}

Пожалуйста, кто-нибудь может помочь мне понять, где я иду не так?

Ответы [ 5 ]

11 голосов
/ 12 января 2012

Также вы можете сортировать NSArray с помощью NSDates методом:

array = [array sortedArrayUsingSelector:@selector(compare:)];

Тогда в [array firstObject] будет первая дата (например, 1970-01-01T00: 00: 00), а последний объект: [array lastObject] будет последней датой: (например, 2011-01-12T00: 00: 00)

7 голосов
/ 12 января 2012

Конечно, вы устанавливаете startDate и endDate в обратном направлении в операторах else if?Разве вы не хотите это:

NSDate *startDate = nil; // Earliest date
NSDate *endDate = nil; // Latest date

for (id entry in myArray) 
{
    NSDate *date = [entry objectForKey:kDate];

    if (startDate == nil && endDate == nil) 
    {
        startDate = date;
        endDate = date;
    }
    if ([date compare:startDate] == NSOrderedAscending)
    {
        startDate = date;
    }
    if ([date compare:endDate] == NSOrderedDescending)
    {
        endDate = date;
    }

    date = nil;
}
3 голосов
/ 13 января 2012

Вы также можете использовать предопределенные константы distantPast и distantFuture, чтобы избежать дополнительной проверки для nil:

NSDate *startDate = [NSDate distantFuture];
NSDate *endDate = [NSDate distantPast];

for (id entry in myArray)
{
    NSDate *date = [entry objectForKey:kDate];

    if ([date compare:startDate] == NSOrderedAscending) { startDate = date; }
    if ([date compare:endDate] == NSOrderedDescending)  { endDate = date; }

    date = nil;
}
2 голосов
/ 23 июня 2013

Вы также можете использовать функции earlierDate: и laterDate: NSDate

NSDate *startDate = [NSDate distantFuture];
NSDate *endDate = [NSDate distantPast];

for (id entry in myArray) 
{
    NSDate *date = [entry objectForKey:kDate];
    startDate = [startDate earlierDate:date];
    endDate = [endDate laterDate:date];
}
0 голосов
/ 02 октября 2016

Просто для других подобных проблем: опция valueForKeyPath: очень аккуратна, я думаю:

[myArray valueForKeyPath:@"@min.self"];
[myArray valueForKeyPath:@"@max.self"];

Это предполагает, что объект в массиве реализует метод compare: так, как вы этого хотите.Я использую его, чтобы получить самую раннюю дату в массиве дат, например.Если вы хотите использовать его здесь, объекты в массиве должны переопределить метод compare:.

...