从数组中删除项目(来自 API 的带有 JSON 的 Restkit 项目)
Posted
技术标签:
【中文标题】从数组中删除项目(来自 API 的带有 JSON 的 Restkit 项目)【英文标题】:Remove items from array (Restkit project with JSON from API) 【发布时间】:2014-06-05 23:58:37 【问题描述】:我有一个leafs
数组,我想删除数组中的一些对象。
数组中有大约 50 个对象,我只想要数组中的大约 10 个;数组中需要的 10 个对象混合在数组中的 50 个对象中。
我在我的项目中使用 RestKit,并将 leafs
放入表视图中。
ViewController.m
@property (strong, nonatomic) NSArray *springs;
@property (strong, nonatomic) NSMutableArray *leafs;
@end
@synthesize tableView=_tableView;
@synthesize springs;
@synthesize leafs;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
[self configureRestKit];
[self loadLeafs];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (void)configureRestKit
// initialize AFNetworking HTTPClient
NSURL *baseURL = [NSURL URLWithString:@"https://api.e.com"];
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
// initialize RestKit
RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];
// setup object mappings
RKObjectMapping *springMapping = [RKObjectMapping mappingForClass:[Spring class]];
[springMapping addAttributeMappingsFromArray:@[@"name"]];
RKObjectMapping *leafMapping = [RKObjectMapping mappingForClass:[Leaf class]];
[leafMapping addAttributeMappingsFromArray:@[@"abbreviation", @"shortName", @"id"]];
[springMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"leafs" toKeyPath:@"leafs" withMapping:leafMapping]];
// Wain, this is where I'm getting that error:
// "property discardsinvalidobjectsoninsert not found on object of type RKObjectMapping"
springMapping.discardsInvalidObjectsOnInsert = YES;
// register mappings with the provider using a response descriptor
RKResponseDescriptor *responseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:springMapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:@"springs"
statusCodes:[NSIndexSet indexSetWithIndex:200]];
[objectManager addResponseDescriptor:responseDescriptor];
- (void)loadLeafs
NSString *apikey = @kCLIENTKEY;
NSDictionary *queryParams = @@"apikey" : apikey,;
[[RKObjectManager sharedManager] getObjectsAtPath:@"v1/springs/"
parameters:queryParams
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
springs = mappingResult.array;
[self.tableView reloadData];
failure:^(RKObjectRequestOperation *operation, NSError *error)
NSLog(@"No springs?': %@", error);
];
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return springs.count;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
Spring *spring = [springs objectAtIndex:section];
return spring.leafs.count;
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
Spring *spring = [springs objectAtIndex:section];
return spring.name;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Spring *spring = [spring objectAtIndex:indexPath.section];
Leaf *leaf = [spring.leafs objectAtIndex:indexPath.row];
cell.textLabel.text = leaf.shortName;
return cell;
春天.h
@property (nonatomic) NSString *name;
@property (nonatomic) NSNumber *id;
@property (nonatomic) NSArray *leafs;
叶子.h
@property (nonatomic) NSString *name;
@property (nonatomic) NSString *abbreviation;
@property (nonatomic) NSString *shortName;
@property (nonatomic) NSNumber *id;
每个 Wain,我在 Spring.h 中添加了这个
@property (nonatomic, assign) BOOL discardsInvalidObjectsOnInsert;
Per Wain,我在 Spring.m 中添加了这种东西
- (BOOL)validateName:(id *)ioValue error:(NSError **)outError
if([(NSString *)*ioValue isEqualToString:@"cricket"])
NSLog(@"old name: %@, new name: %@", self.name, *ioValue);
// Wain: set the names to nil for the objects you don't want
ioValue = nil;
return NO;
// Wain: should I keep this line?
self.discardsInvalidObjectsOnInsert = YES;
else
return YES;
每个 Wain,我在 ViewController.m 中添加了这个
- (void)loadLeafs
NSString *apikey = @kCLIENTKEY;
NSDictionary *queryParams = @@"apikey" : apikey,;
[[RKObjectManager sharedManager] getObjectsAtPath:@"v1/springs/"
parameters:queryParams
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
springs = mappingResult.array;
[self.tableView reloadData];
failure:^(RKObjectRequestOperation *operation, NSError *error)
NSLog(@"No springs?': %@", error);
];
// Wain: filter (using a predicate) the mapping array (name != nil)
NSPredicate *bPredicate = [NSPredicate predicateWithValue:NO];
self.filteredArray = [self.sports filteredArrayUsingPredicate:bPredicate];
成功阻止
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:@"name != nil"];
springs = [mappingResult.array filteredArrayUsingPredicate:filterPredicate];
// You need to loop over the springs after you filter them and then filter the leafs of each spring
for (Spring *spring in springs)
for (Leaf *leaf in spring.leafs)
NSPredicate *filterPredicate2 = [NSPredicate predicateWithFormat:@"shortName != nil"];
leafs = [spring.leafs filteredArrayUsingPredicate:filterPredicate2];
[self.tableView reloadData];
【问题讨论】:
创建一个新的 NSMutableArray,遍历你的数组,将你想要的添加到新数组中? 您使用什么标准来确定是否要移除叶子? @Mike 好问题,我也会在我原来的问题中说明这一点。我想指定leafs
要包含的shortName
s。比如leafs
数组中,我只想要shortName
s:aaa, bbb, ccc, ddd, eee。这样说清楚了吗?
@jraede 感谢您的回复!你有如何做到这一点的链接,或者你可以发布一个sn-p代码吗?我也有点理解我需要尝试做的事情的总体思路,但具体的实现是我在这里做的不足之处?
【参考方案1】:
如果您想在映射期间过滤掉项目,请考虑使用带有 RestKit 的 KVC 验证。
如果您希望设备上的所有项目都可用并且只过滤显示,请使用谓词过滤数组。
【讨论】:
如果我使用谓词,是在loadLeafs
方法中,还是在tableView
方法中,或其他什么?
目前我尝试在cellForRowAtIndexPath
在Leaf *leaf = [spring.leafs objectAtIndex:indexPath.row];
之后但在cell.textLabel.text = leaf.shortName;
之前添加3 行来做谓词,但它不太有效:NSPredicate *predicate = [NSPredicate predicateWithFormat:@"leaf.shortName CONTAINS %@", @"BBB" ]; NSArray *filtered = [leafs filteredArrayUsingPredicate:predicate]; NSLog(@"Filter: %@", filtered);
通常您运行谓词并缓存结果,通常在viewWillAppear:
中调用的方法中,并且只要源数据发生更改(调用RestKit 成功块)。无论如何,在表格方法之前,您需要将过滤后的计数提供给表格视图...
所以在我上面的原始问题中,我更新了 3 个部分的代码以反映我认为你在说什么。 1 - 添加了filterLeafs
方法。 2 - 添加了调用filterLeafs
方法的viewWillAppear
。 3 - 在成功块的末尾调用filterLeafs
。你说的基本是这个吗?当我在 filterLeafs
方法中使用 NSLog 时,null
返回 filtered
数组和 leafs
数组,这让我感到惊讶,因为 leagues
在表格视图中工作正常?
是的,验证名称并在成功块内。所以把springs = mappingResult.array;
改成springs = [mappingResult.array filteredArray...
;【参考方案2】:
按照您的要求进行操作的简单方法如下:
for (Leaf *leaf in leafs)
if (![leaf.shortName isEqualToString:@"aaa"] && ![leaf.shortName isEqualToString:@"bbb"] && ![leaf.shortName isEqualToString:@"ccc"] && ![leaf.shortName isEqualToString:@"ddd"])
[leafs removeObject:leaf];
这基本上会遍历您的叶子对象数组,如果遇到具有除这四个字符串之外的任何东西的 shortName 属性的叶子对象,则该对象将被删除。
【讨论】:
说得有道理,不过我应该把它放在我的 ViewController 哪里? 也许在 loadLeafs 中?对您的代码一无所知,我无法为您提供最佳答案。 我在loadLeafs
中尝试过,并在上面的问题中发布了我的代码,我尝试过,但它没有删除我要求的任何内容。有什么想法或更多细节会有所帮助吗?
首先,您不希望将 for 循环放在另一个循环中,在该循环中循环通过弹簧。把它拿出来,然后再做。其次,右添加 NSLog(@"%@", leafs);在你运行循环之前和之后告诉我输出是什么。
NSLog 在该方法中两次都是null
。假设这可能与 springs = mappingResult.array
被加载在那里有关,因此我试图弄清楚如何获得嵌套在 springs
内的 leafs
?以上是关于从数组中删除项目(来自 API 的带有 JSON 的 Restkit 项目)的主要内容,如果未能解决你的问题,请参考以下文章