按另一个 NSArray 自定义对象对 NSArray 自定义对象进行排序
Sort NSArray custom objects by another NSArray custom objects
我有 2 个不同的带有自定义对象的 NSArray,如下所示,
Item *item1 = [[Items alloc] init];
item1.number = @"1";
item1.serailNumber = @"S01";
Item *item2 = [[Items alloc] init];
item2.number = @"2";
item2.serailNumber = @"S02";
Item *item3 = [[Items alloc] init];
item3.number = @"3";
item3.serailNumber = @"S03";
Item *item4 = [[Items alloc] init];
item4.number = @"4";
item4.serailNumber = @"S04";
Item *item5 = [[Items alloc] init];
item5.number = @"5";
item5.serailNumber = @"S05";
NSArray *items = @[item1, item2, item3, item4, item5];
NSArray *specList = @[@{"number" : @"002", @"serialNumber" : @"S02"},
@{"number" : @"004", @"serialNumber" : @"S04"},
@{"number" : @"003", @"serialNumber" : @"S03"}];
现在我想通过比较“number
”属性.
基于 specList
数组对我的 items
数组进行排序
现在我的预期项目列表是,
@[item2, item4, item3, item1, item5]
我已经查看了下面列出的几个示例,但我不知道如何与自定义对象进行比较。任何帮助将不胜感激,提前致谢。
Sample 1
Sample 2
下面是引用第一个数组对第二个数组进行排序的示例:
NSArray *users = @[@"Dave",@"Mike",@"Joe",@"Jason",@"Kevin"];
NSArray *iqs = @[@110,@145,@75,@122,@130];
NSMutableArray *array = [NSMutableArray array];
for (int idx = 0;idx<[users count];idx++) {
NSDictionary *dict = @{@"Name": users[idx],@"IQ":iqs[idx]};
[array addObject:dict];
}
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"IQ" ascending:NO];
[array sortUsingDescriptors:@[descriptor]];
这应该可以解决问题:
NSArray *sorted = [items sortedArrayUsingComparator:^NSComparisonResult(Item *item1, Item *item2) {
NSInteger indexForItemEquivalent1InSpecList = [self indexForItem:item1 inList:specList];
NSInteger indexForItemEquivalent2InSpecList = [self indexForItem:item2 inList:specList];
return [@(indexForItemEquivalent1InSpecList) compare:@(indexForItemEquivalent2InSpecList)];
}];
NSLog(@"Sorted: %@", sorted);
有:
-(NSInteger)indexForItem:(Item *)item inList:(NSArray *)list
{
for (NSInteger i = 0; i < [list count]; i++)
{
if ([list[i][@"number"] integerValue] == [[item number] integerValue])
{
return i;
}
}
return NSIntegerMax; //If not found, we put it at the end of the list
}
输出:
Sorted: (
"<Item 0x146678f0> number: 2 serial: S02",
"<Item 0x14667e10> number: 4 serial: S04",
"<Item 0x14667900> number: 3 serial: S03",
"<Item 0x14654200> number: 1 serial: S01",
"<Item 0x14667e20> number: 5 serial: S05"
)
我覆盖-description
以使日志更清晰:
-(NSString *)description
{
return [NSString stringWithFormat:@"<%@ %p> number: %@ serial: %@", [self class], self, _number, _serailNumber];
}
换句话说:
您必须在 specList
中找到相应 Item
对象的索引(参见 indexForItem:inList:
)。我使用 integerValue
是因为您使用的是 @"002"
和 @"2",它们不是相等的字符串。
然后在 NSComparator
中比较两个索引。
对于最后的item1
和item5
,我让他们好像。无法保证它们的顺序,因为它们不存在于 specList
中。如果你想按 "ascending" 顺序排列它们,你必须改为:
NSInteger indexForItem1InSpecList = [self indexForItem:item1 inList:specList];
NSInteger indexForItem2InSpecList = [self indexForItem:item2 inList:specList];
if (indexForItem1InSpecList == NSIntegerMax && indexForItem2InSpecList == NSIntegerMax)
{
return [@([[item1 number] integerValue]) compare:@([[item2 number] integerValue])];
}
else
{
return [@(indexForItem1InSpecList) compare:@(indexForItem2InSpecList)];
}
我有 2 个不同的带有自定义对象的 NSArray,如下所示,
Item *item1 = [[Items alloc] init];
item1.number = @"1";
item1.serailNumber = @"S01";
Item *item2 = [[Items alloc] init];
item2.number = @"2";
item2.serailNumber = @"S02";
Item *item3 = [[Items alloc] init];
item3.number = @"3";
item3.serailNumber = @"S03";
Item *item4 = [[Items alloc] init];
item4.number = @"4";
item4.serailNumber = @"S04";
Item *item5 = [[Items alloc] init];
item5.number = @"5";
item5.serailNumber = @"S05";
NSArray *items = @[item1, item2, item3, item4, item5];
NSArray *specList = @[@{"number" : @"002", @"serialNumber" : @"S02"},
@{"number" : @"004", @"serialNumber" : @"S04"},
@{"number" : @"003", @"serialNumber" : @"S03"}];
现在我想通过比较“number
”属性.
specList
数组对我的 items
数组进行排序
现在我的预期项目列表是,
@[item2, item4, item3, item1, item5]
我已经查看了下面列出的几个示例,但我不知道如何与自定义对象进行比较。任何帮助将不胜感激,提前致谢。
Sample 1 Sample 2
下面是引用第一个数组对第二个数组进行排序的示例:
NSArray *users = @[@"Dave",@"Mike",@"Joe",@"Jason",@"Kevin"];
NSArray *iqs = @[@110,@145,@75,@122,@130];
NSMutableArray *array = [NSMutableArray array];
for (int idx = 0;idx<[users count];idx++) {
NSDictionary *dict = @{@"Name": users[idx],@"IQ":iqs[idx]};
[array addObject:dict];
}
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"IQ" ascending:NO];
[array sortUsingDescriptors:@[descriptor]];
这应该可以解决问题:
NSArray *sorted = [items sortedArrayUsingComparator:^NSComparisonResult(Item *item1, Item *item2) {
NSInteger indexForItemEquivalent1InSpecList = [self indexForItem:item1 inList:specList];
NSInteger indexForItemEquivalent2InSpecList = [self indexForItem:item2 inList:specList];
return [@(indexForItemEquivalent1InSpecList) compare:@(indexForItemEquivalent2InSpecList)];
}];
NSLog(@"Sorted: %@", sorted);
有:
-(NSInteger)indexForItem:(Item *)item inList:(NSArray *)list
{
for (NSInteger i = 0; i < [list count]; i++)
{
if ([list[i][@"number"] integerValue] == [[item number] integerValue])
{
return i;
}
}
return NSIntegerMax; //If not found, we put it at the end of the list
}
输出:
Sorted: (
"<Item 0x146678f0> number: 2 serial: S02",
"<Item 0x14667e10> number: 4 serial: S04",
"<Item 0x14667900> number: 3 serial: S03",
"<Item 0x14654200> number: 1 serial: S01",
"<Item 0x14667e20> number: 5 serial: S05"
)
我覆盖-description
以使日志更清晰:
-(NSString *)description
{
return [NSString stringWithFormat:@"<%@ %p> number: %@ serial: %@", [self class], self, _number, _serailNumber];
}
换句话说:
您必须在 specList
中找到相应 Item
对象的索引(参见 indexForItem:inList:
)。我使用 integerValue
是因为您使用的是 @"002"
和 @"2",它们不是相等的字符串。
然后在 NSComparator
中比较两个索引。
对于最后的item1
和item5
,我让他们好像。无法保证它们的顺序,因为它们不存在于 specList
中。如果你想按 "ascending" 顺序排列它们,你必须改为:
NSInteger indexForItem1InSpecList = [self indexForItem:item1 inList:specList];
NSInteger indexForItem2InSpecList = [self indexForItem:item2 inList:specList];
if (indexForItem1InSpecList == NSIntegerMax && indexForItem2InSpecList == NSIntegerMax)
{
return [@([[item1 number] integerValue]) compare:@([[item2 number] integerValue])];
}
else
{
return [@(indexForItem1InSpecList) compare:@(indexForItem2InSpecList)];
}