2010-05-22 5 views
2

J'apprends le cacao/objectif-c. À l'heure actuelle, je traite du codage clé/valeur. Après avoir lu le livre d'Aaron et d'autres sources, j'ai pensé que j'étais capable de laisser les exemples simples et essayer un complexe ...Comment trouver une clé/valeur spécifique (liste de propriétés)

J'essaye de lire la liste de propriété d'iTunes (iTunes Music Library.xml). Je souhaite récupérer les pistes d'une liste de lecture spécifique.

Probablement tout le monde le sait, mais ci-dessous, je mets un morceau de 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> 

Comme vous pouvez le voir, les listes de lecture sont stockées sous forme de dictionnaires dans un tableau, et la clé qui l'identifie est à l'intérieur , pas en tant que <key> le précédant. Le problème est que je ne suis pas capable de comprendre comment rechercher une clé qui est à l'intérieur d'un autre.

Avec le code suivant je peux trouver le tableau dans lequel les listes de lecture sont stockées, mais comment trouver un <dict> spécifique? Dans le premier plist, le dictionnaire a 3 clés pour l'identifier: nom, maître et id. La première playlist a l'id 20117 et le second 45013. Comment obtenir les pistes de la playlist 20117?

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

Ici, à Stackoverflow je trouve ce post, mais je ne suis pas sûr si itérateur sur le tableau et le tester est une bonne idée.

Je suis assez sûr que je pourrais utiliser valueForKeyPath, mais je suis incapable de comprendre comment le faire.

Toute aide est la bienvenue.

TIA,

Bob

+0

Voulez-vous trouver le premier dict qui contient un identifiant de piste donnée? –

+0

Non, par nom de liste de lecture ou par une autre touche. Je vais éditer mon post afin d'ajouter d'autres clés qui sont à l'intérieur dict playlist. –

Répondre

2

Supposons que vous vouliez rechercher le "ID de la Playlist" == 1219 4:

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"]); 
} 

Notez le recensement rapide, dans ce cas, retourneraient qu'un seul enregistrement (le cas échéant)

-1

voir la méthode -propertyList de NSString.

0

Comme il se trouve, NSFastEnumeration (celui où vous dites for (NSDictionary *playlist in Playlists) est tout à fait bien, rapide. Voir here pour plus de détails. Si pour une raison folle vous vraiment ne voulez pas le faire, vous pouvez utiliser - (NSUInteger)indexOfObjectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate NSPredicate a été plus ou moins conçu pour gérer ce type de choses, mais elles sont déroutantes et limitées.En fait, l'itération sur les choses est très rapide, car en l'absence de grandes optimisations de style de base de données, les abstractions de filtrage finissent généralement itérez de toute façon (gaspillez l'efficacité en faisant + construisez + détruisez + l'interface avec divers objets)

Questions connexes