Как найти конкретный ключ / значение (список свойств)

Я изучаю какао / цель-с. Прямо сейчас я занимаюсь кодированием "ключ-значение". Прочитав книгу Аарона и другие источники, я подумал, что могу оставить простые примеры и попробовать сложный ...

Я пытаюсь прочитать список свойств iTunes (iTunes Music Library.xml). Я хотел бы получить треки, содержащиеся в определенном списке воспроизведения.

Наверное, все это знают, но ниже я поместил кусок xml:

<plist version="1.0">
<dict>
   <key>Major Version</key><integer>1</integer>
   ...
   <key>Playlists</key>
   <array>
      <dict>
         <key>Name</key><string>Library</string>
         <key>Master</key><true/>
         <key>Playlist ID</key><integer>20117</integer>
         ...
         <key>Playlist Items</key>
         <array>
            <dict>
               <key>Track ID</key><integer>10281</integer>
            </dict>
            <dict>
               <key>Track ID</key><integer>10283</integer>
            </dict>
            <dict>
               <key>Track ID</key><integer>10285</integer>
            </dict>
            ...
         </array>
      </dict>
      <dict>
         <key>Name</key><string>Classical Music</string>
         <key>Playlist ID</key><integer>45013</integer>
         ...
      </dict>
   </array>
</dict>
</plist>

Как видите, списки воспроизведения хранятся в виде словарей внутри массива, и ключ, который их идентифицирует, находится внутри него, а не как предшествующий ему <key>.

Проблема в том, что я не могу понять, как искать ключ, который находится внутри другого.

С помощью следующего кода я могу найти массив, в котором хранятся списки воспроизведения, но как найти конкретный <dict>? В приведенном выше списке словаря есть 3 ключа для его идентификации: имя, мастер и идентификатор. Первый плейлист имеет идентификатор 20117, а второй - 45013. Как получить треки плейлиста 20117?

NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:file];
NSArray *playlists = [rootDict objectForKey:@"Playlists"];

Здесь, в Stackoverflow, я нашел это сообщение, но я не уверен, что перебираю массив и проверить это хорошая идея.

Я совершенно уверен, что смогу использовать valueForKeyPath, но не могу понять, как это сделать.

Любая помощь приветствуется.

TIA,

Боб


person Bob Rivers    schedule 22.05.2010    source источник
comment
Вы хотите найти первый диктатор, содержащий заданный идентификатор трека?   -  person Georg Fritzsche    schedule 23.05.2010
comment
Нет, по названию списка воспроизведения или по другой клавише. Я отредактирую свой пост, чтобы добавить другие ключи, которые находятся внутри dict плейлиста.   -  person Bob Rivers    schedule 23.05.2010


Ответы (3)


Предположим, вы хотите найти «Идентификатор плейлиста» == 12194:

NSString *path = [[NSBundle mainBundle] pathForResource:@"iTunes Music Library" ofType:@"xml"];
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSArray *playlists = [rootDict objectForKey:@"Playlists"];

NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K == %@", @"Playlist ID", 
                          [NSNumber numberWithInt:12194]];
NSArray *filteredArray = [playlists filteredArrayUsingPredicate:pred];

for (NSDictionary *dict in filteredArray) {
     NSLog(@"Name = %@", [dict valueForKey:@"Name"]);
     NSLog(@"Playlist ID = %@", [dict valueForKey:@"Playlist ID"]);
}

Обратите внимание, что быстрое перечисление в этом случае вернет только одну запись (если есть)

person unixo    schedule 30.05.2010

Оказывается, NSFastEnumeration (тот, где вы говорите for (NSDictionary *playlist in Playlists), вполне, ну, быстро. См. здесь, чтобы узнать подробности. Если по какой-то безумной причине вы действительно не хотите этого делать, вы может использовать - (NSUInteger)indexOfObjectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate, но это, вероятно, в любом случае выполняет итерацию по массиву. Материал NSPredicate был более или менее разработан для обработки этого типа вещей, но они сбивают с толку и ограничены. абстракции обычно в конечном итоге все равно повторяются (тратя впустую эффективность, заставляя вас создавать + уничтожать + интерфейс с различными объектами).

person Jared Pochtar    schedule 23.05.2010

см. -propertyList метод NSString.

person NSResponder    schedule 23.05.2010