Вопрос по iphone, ios, core-data, collections – Основной алгоритм сравнения массивов

1

Я пытаюсь следоватьшаги найдены здесь сравнивая два массива и зная, когда создать новый объект, но я просто не понимаю, как он работает:

You end up with two sorted arrays—one with the employee IDs passed into the fetch request, and one with the managed objects that matched them. To process them, you walk the sorted lists following these steps:

Get the next ID and Employee. If the ID doesn't match the Employee ID, create a new Employee for that ID.
Get the next Employee: if the IDs match, move to the next ID and Employee.

Regardless of how many IDs you pass in, you only execute a single fetch, and the rest is just walking the result set.

В основном происходит то, что у меня есть массив идентификаторов объектов из внешнего источника, а клиентская система имеет только подмножество объектов, представленных этими идентификаторами. Мне нужно выяснить, какие объекты у меня уже есть, и если у меня их нет, создайте их один за другим.

Я не понимаю, как это работает. У меня проблемы с переводом этого кода:

for (int i =0;i<ids.count;i++) {
    currentId = [ids objectAtIndex:i];
    currentObject = [objects objectAtIndex:i];

    if(currentObject.id != currentId) {
        //create new object
    }

    //"get the next employee"
    //uh what?
    nextEmployee = [objects objectAtIndex:i+1]; //?
    if(nextEmployee.id == currentId) {
        //"move on to the next id"
        continue;
    }
}

Я не вижу, как это будет работать? Что мне не хватает?

Хорошо. Смотрите мою ниже реализацию алгоритма pasawaya
Какую ошибку вы получаете? Что не работает? pasawaya
Если у вас есть какие-либо вопросы по поводу моего кода, просто задайте его в комментариях pasawaya
Я просто не понимаю, как отобразить это в коде. Я уверен, что моя реализация неверна, нет? Я просто не понимаю, как работает весь алгоритм .. Snowman

Ваш Ответ

4   ответа
0

NSArray *wholeList = [[NSArray alloc]initWithObjects:@"employee1", @"employee2", @"employee3", @"employee4", @"employee5",@"employee6", nil];
NSArray *partialList = [[NSArray alloc]initWithObjects:@"employee2", @"employee13", @"employee7", nil];

for (id employeeID in partialList)  //get one employee from the partialList
{
    if (![wholeList containsObject:employeeID])  //check to see if it is in the wholeList
    {
        NSLog(@"This employee is not in the wholeList: %@", employeeID);
        // do create new employee object for this employeeID, whatever...
    }
}
Это не так эффективно, как рекомендует Apple. У вас есть цикл for с O (n), а затем [список содержитObject:], который я тоже считаю O (n). Способ сверху более эффективен, я просто не знаю, как его реализовать Snowman
0

//Employee.h
@property (nonatomic) NSInteger ID;
@property (nonatomic, strong) NSString *name;

//Employee.m
@synthesize ID, name;



//Place where you put algorithm
#import "Employee.h"
------------------------
NSMutableArray *employeeIDs = [NSArray arrayWithObjects:[NSNumber numberWithInt:123], [NSNumber numberWithInt:456], [NSNumber numberWithInt:789], nil];

//Creates employee objects
Employee *employee1 = [[Employee alloc] init];
employee1.ID = 123;
employee1.name = @"John Smith";

Employee *employee2 = [[Employee alloc] init];
employee2.ID = 456;
employee2.name = @"Bob Day";

Employee *employee3 = [[Employee alloc] init];
employee3.ID = 789;
employee3.name = @"Steve Jobs";

NSMutableArray *employeesArray = [NSArray arrayWithObjects:employee1, employee2, employee3, nil];

for (int index = 0; index <= [employeeIDs count]; index++) {

    for(id currentEmployee in employeesArray){

        if(currentEmployee.ID != currentID){

            Employee *newEmployee = [[Employee alloc] init];
            newEmployee.name = [NSString stringWithFormat:@"Employee Name"];
            newEmployee.ID = 384;

            [employeeIDs addObject:[NSNumber numberWithInteger:newEmployee.ID]];
            [employees addObject:newEmployee.name];

        }
    }
}

Надеюсь это поможет!

@mohabitar Это то, что Apple говорила. Во-первых, он перебирает идентификаторы сотрудников и проверяет, соответствует ли этот идентификатор кому-либо из сотрудников. Я БЫ. Если это так, он переходит к следующему идентификатору. Если он не совпадает, он создает нового сотрудника.
Я не вижу, как это может работать. Это перебираетemployeesArray каждый раз для каждогоemployeeID, Итакif (currentEmployee.ID != currentID) условие будет выполнено много раз.
Подождите, это так же, как Apple, или это другая реализация? Snowman
0

чтобы проверить, можете ли вы его найти, возможно, что-то вроде этого:

for (int i = 0; i < ids.count; i++) {
    bool found = NO;
    currentId = [ids objectAtIndex:i];

    // We need to traverse the whole array to check if we can find the objectID somewhere...
    for(int j = 0; j < objects.count; j++) {
        currentObject = [objects objectAtIndex:j];

        if (currentId == currentObject) {
            found = YES;
            break;
        }
    }

    if (!found)
    {
        // Create the new object
    }
}
Я не знаю, что вы говорите о «подходе Apple» ...
Да, но в подходе Apple нет только одного цикла for? Snowman
Это не так эффективно, как Apple рекомендует. Snowman
Тот, на мой вопрос .. Snowman
У вас есть 2 массива без конкретных порядков (я полагаю), поэтому бинарный поиск не будет полезным. Возможно, у меня нет всей информации о вашей проблеме, но из того, что я вижу, вам потребуется 2for цикл, чтобы пройти второй, делая его O (n ^ 2) ...
1

посмотрев тот же пример в Руководстве по программированию основных данных.

Это мое решение:

Ключ заключается в том, что вы проходите 2 массива отдельно, один массив содержит все строки employeeId, которые должны существовать в Базовых данных, а другой содержит объекты Employee, которые уже существуют в Базовых данных, отфильтрованные по строкам employeeId. Оба массива были отсортированы.

Допустим, у нас есть отсортированный массив employeeIds, содержащий строки:

@"10",@"11",@"12",@"15",@"20"

И что у нас есть массив matchEmployees, содержащий 2 объекта Employee с employeeId 10 и 15.

Нам необходимо создать новые объекты Employee для сотрудников с идентификаторами сотрудников 11, 12 и 20, потенциально обновляя атрибуты сотрудников 10 и 15. Так:

int i = 0; // employeeIds array index
int j = 0; // matchingEmployees array index

while ((i < [employeeIds count]) && (j <= [matchingEmployees count])){

  NSString *employeeId = [employeeIds objectAtIndex:i];

  Employee *employee = nil;

  if ([matchingEmployees count]!=0)
      employee = [matchingEmployees objectAtIndex:j];

  if (![employeeId isEqualToString:employee.employeeId]){

      employee = //Insert new Employee entity into context
      employee.employeeId = employeeId;

      //Set any attributes for employee that do not change
  }
  else {
      //We matched employeeId to Employee so the next iteration
      //of this loop should check the next Employee object
      j++; 
  }

  //Set any attributes for employee that change with each update

  i++;
}

Похожие вопросы