Ключ перевірки існує в NSDictionary


76

як я можу перевірити, чи існує це ?:

[[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"]

Я хочу знати, існує цей ключ чи ні. Як я можу це зробити?

Дуже дякую :)

EDIT: dataArray містить об’єкти. І ці об’єкти - словники NSD.


Будь-яка причина, чому ви використовуєте -valueForKey:замість -objectForKey:? Перший використовується в кодуванні ключ-значення і дещо повільніший за другий.

Відповіді:


158

Я припускаю, що [dataArray objectAtIndex:indexPathSet.row]повертає NSDictionary, і в такому випадку ви можете просто перевірити результат valueForKeyпротиnil.

Наприклад:

if ([[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"] != nil) {
    // The key existed...

}
else {
    // No joy...

}

значення цього ключа також може бути нульовим, тому цей підхід не буде повністю перевірити, чи існує ключ у словнику чи ні
Андрій А.

1
@ AndreiA. Ви не можете додати нуль до словника NSD.
Джон Паркер,

46

Отже, я знаю, що ви вже вибрали відповідь, але я знайшов це досить корисним як категорію NSDictionary. На цьому етапі ви починаєте отримувати ефективність із усіма цими різними відповідями. Ме ... 6 з 1 ...

- (BOOL)containsKey: (NSString *)key {
     BOOL retVal = 0;
     NSArray *allKeys = [self allKeys];
     retVal = [allKeys containsObject:key];
     return retVal;
}

Я також написав той самий метод у своїй категорії, але трапився дивний збій, коли я використовую UIImageWriteToSavedPhotosAlbum (). після звуження, я міняю назву методу з containsKey => hasKey, і збій зник
kaala

Це набагато краще прийнятої відповіді. Я хочу шукати за ключем, а не якщо значення ключа дорівнює нулю чи ні. Ви можете мати ключ у словнику, який вказує на значення нуль. Проте ключ існує. Прийнята відповідь не охоплює цей сценарій. Але це рішення тут робить.
Houman

3
@Hooman: Неправда щодо ключа, що має значення nil: другий абзац документації NSDictionary ( developer.apple.com/library/mac/documentation/Cocoa/Reference/… ) говорить, що "Ні ключ, ні значення не можуть бути нульовим; якщо вам потрібно представити нульове значення у словнику, вам слід використовувати NSNull. " І ця, і прийнята відповідь працюють для вашого сценарію, тобто зі словником, де значення для якогось ключа є нульовим (типу NSNull).
Ярно Ламберг

1
Або: return [[self allKeys] containsObject: key]? ТАК НІ;
посмішка,

3
хороша виноска, @Jamo. Я б уникав цієї відповіді. я припускаю, що під ковдрами як виклик allKeys, так і виклик containsObject є принаймні O (n), тоді як valueForKey, ймовірно, набагато менше.
orion elenzil

34

Перевірте, чи нуль:

if ([[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"] != nil) {
    // SetEntries exists in this dict
} else {
    // No SetEntries in this dict
}

значення цього ключа також може бути нульовим, тому такий підхід не буде повністю перевірити, чи існує ключ у словнику чи ні
Андрій А.

@AndreiA. Ні ключ, ні значення не можуть бути nilв словнику NSD. Щоб представити нуль, ви можете використовувати NSNull.
Аарон Еш,

9

це також працює за допомогою літералів Objective-C, використовуючи такий синтаксис:

NSDictionary *dict = @{ @"key1" : @"value1", @"key2" : @"value2" };
if (dict[@"key2"])
NSLog(@"Exists");
else
NSLog(@"Does not exist");

Для швидкої версії нижче код працює. нехай заголовки: Dictionary = httpResponse .allHeaderFields if (headers ["errorcode"]! = nil) {print ("ключ помилки існує")}
Narasimha Nallamsetty

0
if ((NSNull *)[[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"] != nil) {
    // SetEntries exists in this dict
} else {
    // No SetEntries in this dict
}

Це правильна відповідь.


1
для чого потрібен акторський склад з BOOL на NSNull *?
NiñoScript

0

Спробуйте це:

if ([dict objectForKey:@"bla"]) {
   // use obj
} else {
   // Do something else like create the object
}

1
Це може бути технічно правильним поясненням, але ви будете слугувати громаді краще (і, ймовірно, отримуватимете більше голосів), якщо ви надасте більш детальну дискусію про свої міркування в тілі своєї відповіді. Чому доцільно використовувати objectForKey:замість іншого методу? Чому вам не потрібно явно перевіряти значення? Принаймні, використання прикладу коду, наведеного у питанні, полегшить прив’язку вашого прикладу до вихідного питання.
Палпатим

0

Цей робить те саме, але з меншим кодом:

if (dataArray[indexPathSet.row][@"SetEntries"] != nil) { /* the key exists */        } 
else                                                   { /* the key doesn't exist */ }

0

Перевірити словник містить будь-яке значення. Я вважаю за краще [dic allKeys] .count> 0 перевіряти.


0

Використовуйте (unsigned long)опцію:

if ( (unsigned long)[[dataArray objectAtIndex:indexPathSet.row] valueForKey:@"SetEntries"] ) {
    // Key exist;
}else{
    // Key not exist;
};
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.