比较两个数组的内容并找出差异

时间:2013-05-16 02:16:55

标签: ios core-data nsarray

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

我从中提取的数据与每个人都有关联。当我创建一个新的“人”实体时,我也用它保存了这个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];

我按照相同的方式对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];


            }];

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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]]];

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

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

    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

答案 2 :(得分: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 }