2014-01-24 1 views
1

Я видел много примеров для Custom sort для NSMutableArray, здесь один из них How to sort an NSMutableArray with custom objects in it?, но у меня есть объект с a и b, и я хочу отсортировать их согласно а * Ь.Каков наилучший способ для пользовательского сортировки для NSMutableArray, который содержит объекты

Я видел этот код, например

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

Но я не BirthDate здесь мне нужно сортировать в соответствии с * Ь (как двойной)?

Подробнее,

У меня есть NSMutableArray, содержащий объекты CGRect, и я хочу, чтобы отсортировать их по ширине * высота

+4

Что такое «a * b»? – Kreiri

+0

вы можете добавить несколько дескрипторов сортировки, если хотите отсортировать по нескольким параметрам. – Stas

+1

Вы пытаетесь отсортировать массив с использованием объектов даты? – Balu

ответ

2

NSSortDescriptor не подходит ни для чего более сложного, чем сравнения простого ключа, или, возможно, набор ключей.

Вы хотите отсортировать данные с помощью специального компаратора (блока). Что-то вроде

sortedArray = [myArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) { 
    MyObject *first = (MyObject*)a; 
    MyObject *second = (MyObject*)b; 

    if (first.a * first.b < second.a * second.b) { 
     return NSOrderedAscending; 
    } 
    else if (first.a * first.b > second.a * second.b) { 
     return NSOrderedDescending; 
    } 
    return NSOrderedSame; 
}] 

Примечание Я просто окрыления его, насколько ваш (а * б) описание идет, на самом деле не уверен, что вы хотите там.

1

Самый простой способ реализовать пользовательскую сортировку - использовать -[NSMutableArray sortUsingComparator: или -[NSArray sortedArrayUsingComparator:].

sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 
    // Compare stuff, return a NSComparisonResult. 
    return [obj1 compare:obj2]; 
}]; 

Мне нравится явно передавать типы объектов в блоке, BTW. Например, для строк:

sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) { 
    // Compare stuff, return a NSComparisonResult. 
    return [obj1 localizedCaseInsensitiveCompare:obj2]; 
}]; 
2

Я согласен с предыдущими решениями. Вы можете поместить CGRects в массив, обернув их в NSValue:

CGRect rect = CGRectMake(0, 10, 20, 30); 
NSValue *valueToPutInArray = [NSValue valueWithCGRect:rect]; 

и сортировать их с блоком, как это:

NSArray *sortedArray = [rectArray sortedArrayUsingComparator:^NSComparisonResult(NSValue *rectAValue, NSValue *rectBValue) { 
     CGRect rectA = [rectAValue CGRectValue]; 
     CGRect rectB = [rectBValue CGRectValue]; 

     CGFloat areaA = rectA.size.width * rectA.size.height; 
     CGFloat areaB = rectB.size.width * rectB.size.height; 

     if (areaA < areaB) 
     { 
      return NSOrderedAscending; 
     } 
     else if (areaB > areaA) 
     { 
      return NSOrderedDescending; 
     } 
     else 
     { 
      return NSOrderedSame; 
     } 
    }]; 

Другим решением было бы обернуть CGRect в пользовательский объект и добавить функцию к ней, как

- (CGFloat)area 
{ 
    return self.rect.size.width * self.rect.size.height; 
} 

(self.rect это завернутые прямоугольник) Если вы заполнить ваш массив с этими пользовательскими объектами вы можете сортировать его с оригинальной мной ThOD путем создания своего рода дескриптор, как

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"area" ascending:YES]; 

это будет просто сравнить результаты функции области и сортировки массива нарастающий к этому.

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