1

我有两个数组,一个是来自核心数据(array1)的获取请求的数组,另一个是从 web(array2)中提取的数据。我想做的是将array1与array2进行比较,并且array2中不在array1中的任何项目都需要添加到核心数据中。

我从中提取的数据具有与每个人相关联的 ID。当我创建一个新的“人”实体时,我也会用它来保存这个 ID。我不确定如何使用 Person 的 id 比较数组,甚至不知道如何在数组中访问它。

这是获取请求:

NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    NSError *error = nil;
    [fetch setEntity:[NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.managedObjectContext]];
    NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"Pid" ascending:YES];
    request.sortDescriptors = @[sorter];
    NSArray *items = [self.managedObjectContext executeFetchRequest:request error:&error];

我以与对新数据排序的 array2 相同的方式对 fetch 进行排序。我只是不确定如何比较两者,然后将新项目添加到核心数据中。请帮忙?

更新:

    NSDictionary *qDict = [JSON objectForKey:@"person"];
        NSArray *qArry = [JSON objectForKey:@"person"];

//Used to print the id's
        _testArray = [NSMutableArray arrayWithArray:[qDict valueForKey:@"id"]];
        for (NSNumber *numb in _testArray) {
            NSLog(@"id = %@", numb);
        }


        NSError *error = nil;
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Pid IN %@", [qDict valueForKey:@"Pid"]];
        [fetchRequest setPredicate:predicate];
        [fetchRequest setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"Pid" ascending:YES]]];
        NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
        NSLog(@"%d how many items from the fetch", items.count);

        for (NSDictionary *qdt in qArry) {

            NSUInteger currentIndex = 0;
            Person *q = nil;

            if ([items count] > currentIndex) {
                q = [items objectAtIndex:currentIndex];
            }

            if ([q.Pid integerValue] == [[qdt objectForKey:@"id"] integerValue]) {
                // Either update the object or just move on

            }

            else {
                // Add the object to core data
                q = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
                q.url = [qdt valueForKey:@"url"];
                q.Pid = [qdt objectForKey:@"id"];
                q.text = [qdt valueForKey:@"personText"];
                NSError *error = nil;
                [_managedObjectContext save:&error];


            }
            currentIndex++;
        }

        //[_managedObjectContext save:&error];

    }
            failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)  {
                UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error retrieving data" message:@"Please try again" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];

                [av show];


            }];
4

3 回答 3

1

也许你可以做这样的事情:

NSMutableArray *webData = [NSMutableArray arrayWithObjects:@"object 1",@"object 2",@"object 3",@"object 4", nil];
NSMutableArray *coreData = [NSMutableArray arrayWithObjects:@"object 2",@"object 4", nil];

NSMutableArray *newData = [NSMutableArray arrayWithArray:webData];
[newData removeObjectsInArray:coreData];

//output "object 1", "object 3"

或者,如果您在数组中有一个自定义 NSObject 并将其与其主键进行比较,也许您可​​以执行以下操作:

NSMutableArray *webData = [NSMutableArray arrayWithObjects:test1,test2,test3,test4, nil];
NSMutableArray *coreData = [NSMutableArray arrayWithObjects:test2,test3, nil];



__block NSMutableArray *newData = [NSMutableArray new];
[webData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    __block testObject *object = (testObject *)obj;

    __block BOOL isExisting = NO;
    [coreData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        testObject *innerObject = (testObject *)obj;
        if(object._id == innerObject._id)
            isExisting = YES;
    }];
    if(!isExisting)
        [newData addObject:object];
}];
//output will be object 1 and object 4
于 2013-05-16T03:09:08.523 回答
1

首先,您可以根据从网络上检索到的人员 ID (idArray) 获取存储在核心数据中的对象列表,并根据 ID 对它们进行排序:

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id IN %@", idArray];
[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES]]];

这将为您返回对象列表,该 ID 也可以在您从 Web 检索的对象中找到。让我们称这个storedRecords数组。然后您可以执行以下操作:

  1. 设置计数器,
  2. 遍历下载的数组(这是包含从网络检索到的对象的数组,它也必须按 id 排序),
  3. 在 storedRecords 数组中使用 objectAtIndex,
  4. 检查 storedManagedObject 的 id 是否与记录对象的 id 匹配,如果不匹配,则它是一个可以保存到核心数据中的新对象。否则,它是一个现有对象。
  5. 增加计数器。

这是一个例子:

int currentIndex = 0;
for (NSDictionary *record in downloadedArray) {
    NSManagedObject *storedManagedObject = nil;
    if ([storedRecords count] > currentIndex) {
        storedManagedObject = [storedRecords objectAtIndex:currentIndex];
    }
    if ([[storedManagedObject valueForKey:@"id"] integerValue] == [[record valueForKey:@"id"] integerValue]) {
        //this will be existing object in core data
        //you can update the object if you want
    } else {
        //this will be new object that you can store into core data
    }
    currentIndex++;
}

这类似于此处提到的内容:

http://www.raywenderlich.com/15916/how-to-synchronize-core-data-with-a-web-service-part-1

于 2013-05-16T03:57:58.017 回答
0

尝试这个

NSMutableArray *array1 = [[NSMutableArray alloc] initWithObjects:@"a",@"a",@"a",@"d",@"b",@"b",@"c",@"a",@"c",nil];

NSMutableArray *array2 = [[NSMutableArray alloc] initWithObjects:[NSString stringWithFormat:@"%@",[array1 objectAtIndex:0]], nil];;

for(int i = 0;i<[array1 count];i++)
{
    if ([array2 containsObject:[array1 objectAtIndex:i]]) {
        NSLog(@"do nothing");
    }
    else{
        [array2 addObject:[array1 objectAtIndex:i]];
        NSLog(@"array2 is %@",array2);
    }
    NSLog(@"finally array2 is %@",array2);

}

array2 将作为{ a,d,b,c }

于 2014-08-07T11:12:26.020 回答