Как получить индекс объекта? - PullRequest
1 голос
/ 20 января 2012

Как я могу получить свой индекс объекта? У меня есть словарь, содержащий массивы, и внутри массивов у меня есть несколько словарей.

Моя структура данных (например):

Студент ------ NSDictionary

   Item 0 ------ NSArray<br>
          Name ----- Grace<br>
          Age ----- 20<br>
   Item 1 ------ NSArray<br>
          Name ----- Anne<br>
          Age ----- 21<br>             

Так, например, у меня есть значение имени, Грейс, и я хочу получить значение массива индекса объекта (в данном случае, элемент 0). Как я могу это сделать?

Я использовал indexOfObject, однако я получил результат 2147483647, что, по-моему, означает nsnotfound. Поэтому я думаю, что это не работает для этого случая.

Это мои коды:

NSMutableDictionary* namevalue = [[NSMutableDictionary alloc] init];    
namevalue = [somedict objectForKey:@"Name"];              
int arryindex;
arryindex = [somearray indexOfObject:namevalue];                
NSLog(@"Array Index:%i", arryindex);

Кто-нибудь может помочь? Большое вам спасибо!

Ответы [ 2 ]

2 голосов
/ 20 января 2012

В вашем коде вы забыли включить создание somedict и somearray.Проблема может быть там.

Также вам не нужно присваивать namevalue пустой словарь, а затем фактический словарь внутри массива.

Проверьте этот фрагмент рабочего кода:

NSUInteger idx;
NSDictionary *john = [NSDictionary dictionaryWithObjectsAndKeys:@"John", @"name", 
                         [NSNumber numberWithInt:23], @"age", nil];
NSDictionary *jane = [NSDictionary dictionaryWithObjectsAndKeys:@"Jane", @"name", 
                         [NSNumber numberWithInt:24], @"age", nil];    
NSArray *students = [NSArray arrayWithObjects:john, jane, nil];
idx = [students indexOfObject:john];
NSLog(@"john is at: %i", idx == NSNotFound ? -1 : idx); /* 0 */
idx = [students indexOfObject:jane];
NSLog(@"jane is at: %i", idx == NSNotFound ? -1 : idx); /* 1 */

Теперь попробуйте использовать объект, отсутствующий в массиве:

NSDictionary *mary = [NSDictionary dictionaryWithObjectsAndKeys:@"Mary", @"name", 
                         [NSNumber numberWithInt:22], @"age", nil];        
idx = [students indexOfObject:mary];
NSLog(@"mary is at: %i", idx == NSNotFound ? -1 : idx); /* -1 Not found */

И, наконец, новый объект, созданный как точная копия объекта, уже присутствующего в массиве:

NSDictionary *maryjane = [NSDictionary dictionaryWithObjectsAndKeys:@"Jane", @"name", 
                             [NSNumber numberWithInt:24], @"age", nil];            
idx = [students indexOfObject:maryjane];
NSLog(@"maryjane is at: %i", idx == NSNotFound ? -1 : idx); /* 1 */

Метод indexOfObject будет использовать isEqual: для сравнения объектов.Вы можете убедиться, что новый объект будет считаться равным объекту в массиве:

NSLog(@"jane is maryjane? %i", [jane isEqual:maryjane]); /* 1 */
0 голосов
/ 20 января 2012

Если я правильно понял, вы ищете способ найти индекс объекта в NSDictionary на основе значения свойства, которое имеет объект, верно?
Например, в вашем словаре students есть ученик с именем Graceи вы хотели бы знать, по какому индексу хранится объект учащегося с именем Grace ...

Если выше верно, вот мое (неполное и грубое) решение, которое работает только для объектов со свойствами NSString, но как только вы поймете идею ниже, я думаю, вы сможете изменить код в соответствии со своими потребностями.

- (NSInteger)indexOfObjectWithPropertyValue:(id)value inDictionary:(NSDictionary *)dict {
    NSInteger objectIndex = 0;
    unsigned int outCount, i;

    for (id key in dict) {
        id objForKey = [dict objectForKey:key];
        Class lender = [objForKey class];

        objc_property_t *properties = class_copyPropertyList(lender, &outCount);

        for (i = 0; i < outCount; i++) {
            objc_property_t property = properties[i];
            id v = [objForKey valueForKey:[NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding]];

            if ([v isKindOfClass:[value class]] && [v isEqual:value]) {
                return objectIndex; 
            }
        }
        objectIndex++;
    }

    return NSNotFound; // i.e. NSIntegerMax
}

и не забудьте включить заголовок времени выполнения:

#import <objc/runtime.h>

Мой код может и, вероятно, иметь некоторые проблемы:

  • самый очевидный isEqual: метод, который должен сравнивать значения свойств.
  • над кодомне охватывает ситуацию, когда есть много объектов с одинаковой ценностью (как у многих студентов с одинаковым именем!)
  • ???

Я надеюсь, что мой "ответ" сделает этоВам проще реализовать то, что вам нужно.

...