Как мне отсортировать NSMutableArray с пользовательскими объектами в нем?

Возможно, у меня есть решение, которое я указал на расхождение Ян Коритак

SELECT CONCAT('SELECT ',
( SELECT GROUP_CONCAT(t.col)
FROM
(
    SELECT CASE
    WHEN COLUMN_NAME = 'eid' THEN NULL
    ELSE COLUMN_NAME
    END AS col 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test'
) t
WHERE t.col IS NOT NULL) ,
' FROM employee' );

. Таблица:

SELECT table_name,column_name 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test'

============= ===================

table_name  column_name
employee    eid
employee    name_eid
employee    sal

========================== ===========

Результат запроса:

'SELECT name_eid,sal FROM employee'
1237
задан Peter Mortensen 28 November 2017 в 13:57
поделиться

4 ответа

Метод сравнения

Либо вы реализуете метод сравнения для своего объекта:

- (NSComparisonResult)compare:(Person *)otherObject {
    return [self.birthDate compare:otherObject.birthDate];
}

NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(compare:)];

NSSortDescriptor (лучше)

или обычно даже лучше:

NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                           ascending:YES];
NSArray *sortedArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];

Вы можете легко отсортировать по нескольким ключи, добавив более одного в массив. Использование пользовательских методов сравнения также возможно. Посмотрите документацию .

Блоки (блестящие!)

Существует также возможность сортировки по блокам начиная с Mac OS X 10.6 и iOS 4: производительность

NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    NSDate *first = [(Person*)a birthDate];
    NSDate *second = [(Person*)b birthDate];
    return [first compare:second];
}];

-сравнить: и методы, основанные на блоках, будут в целом немного быстрее, чем использование NSSortDescriptor , так как последний полагается на KVC. Основное преимущество метода NSSortDescriptor заключается в том, что он позволяет определять порядок сортировки с помощью данных, а не кода, что позволяет легко, например,

2289
ответ дан 19 December 2019 в 20:15
поделиться

Ваши объекты Person должны реализовать метод, скажем, сравнить: , который принимает другой объект Person , и вернуть ] NSComparisonResult в соответствии с отношениями между двумя объектами.

Затем вы вызываете sortedArrayUsingSelector: с @selector (сравните:) , и это должно быть сделано.

Существуют и другие способы, но, насколько мне известно, нет какао-эквивалента интерфейса Comparable . Использование sortedArrayUsingSelector: , вероятно, самый безболезненный способ сделать это.

16
ответ дан 19 December 2019 в 20:15
поделиться

См. Метод NSMutableArray sortUsingFunction: context:

Вам необходимо настроить функцию сравнения , которая принимает два объекта ( типа Person , поскольку вы сравниваете два объекта Person ) и параметр context .

Эти два объекта являются просто экземплярами Person . Третий объект - это строка, например @ "birthDate".

Эта функция возвращает NSComparisonResult : возвращает NSOrderedAscending , если PersonA.birthDate < ] PersonB.birthDate . Он вернет NSOrderedDescending , если PersonA.birthDate > PersonB.birthDate . Наконец, он вернет NSOrderedSame , если PersonA. birthDate == PersonB.birthDate .

Это грубый псевдокод; вам нужно будет уточнить, что означает, что одна дата «меньше», «больше» или «равна» другой дате (например, сравнение секунд с тех пор и т. д.):

NSComparisonResult compare(Person *firstPerson, Person *secondPerson, void *context) {
  if ([firstPerson birthDate] < [secondPerson birthDate])
    return NSOrderedAscending;
  else if ([firstPerson birthDate] > [secondPerson birthDate])
    return NSOrderedDescending;
  else 
    return NSOrderedSame;
}

Если вы хотите что-то более компактное , вы можете использовать троичные операторы:

NSComparisonResult compare(Person *firstPerson, Person *secondPerson, void *context) {
  return ([firstPerson birthDate] < [secondPerson birthDate]) ? NSOrderedAscending : ([firstPerson birthDate] > [secondPerson birthDate]) ? NSOrderedDescending : NSOrderedSame;
}

Встраивание может, возможно, немного ускорить это, если вы делаете это много.

107
ответ дан 19 December 2019 в 20:15
поделиться

Во втором ответе Георга Шелли отсутствует шаг, но тогда он работает нормально.

NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                              ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptor:sortDescriptors];
19
ответ дан 19 December 2019 в 20:15
поделиться