如何查找特定的键/值(属性列表)

发布于 2024-09-02 08:53:33 字数 2101 浏览 3 评论 0原文

我正在学习可可/objective-c。现在我正在处理键/值编码。阅读 Aaron 的书和其他资料后,我认为我能够离开简单的示例并尝试复杂的示例...

我正在尝试读取 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>

如您所见,播放列表作为字典存储在数组中,标识它的键位于其中,而不是作为 。位于其前面。

问题是我无法弄清楚如何搜索另一个密钥中的密钥。

使用以下代码我可以找到存储播放列表的数组,但是如何找到特定的?在上面的plist中,字典有3个键来识别它:name、master和id。第一个播放列表的 ID 为 20117,第二个播放列表的 ID 为 45013。如何获取播放列表 20117 的曲目?

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

在 Stackoverflow 上,我发现了这篇 post,但我不确定是否迭代数组并测试一下是个好主意。

我很确定我可以使用 valueForKeyPath,但我无法弄清楚如何做到这一点。

欢迎任何帮助。

蒂亚,

鲍勃

I'm learning cocoa/objective-c. Right now I'm dealing with key/value coding. After reading Aaron's book and other sources, I thought that I was able to left the simple examples and try a complex one...

I'm trying read iTunes property list (iTunes Music Library.xml). I would like to retrieve the tracks held by an specific playlist.

Probably everybody knows it, but bellow I put a piece of the 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>

As you can see, the playlists are stored as dictionaries inside an array, and the key that identifies it is inside it, not as a <key> preceding it.

The problem is that I'm not able to figure out how to search for a key that is inside another one.

With the following code I can find the the array in which the playlists are stored, but how to find an specific <dict>? In above plist, the dictionary has 3 keys to identify it: name, master and id. The first playlist has the id 20117 and de second 45013. How to get the tracks of playlist 20117?

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

Here at Stackoverflow I found this post, but I'm not sure if iterate over the array and test it is a good idea.

I'm quite sure that I could use valueForKeyPath, but I'm unable to figure out how to do it.

Any help is welcome.

TIA,

Bob

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

糖果控 2024-09-09 08:53:33

假设您要搜索“播放列表 ID”== 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"]);
}

请注意快速枚举,在这种情况下,只会返回一条记录(如果有)

Supposing you want to search the "Playlist ID" == 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"]);
}

Note the fast enumeration, in this case, would return only one record (if any)

财迷小姐 2024-09-09 08:53:33

事实证明,NSFastEnumeration(您所说的 for (NSDictionary *playlist in Playlists) 相当快。请参阅 此处了解详细信息。如果出于某种疯狂的原因您真的不想这样做,你可以使用 - (NSUInteger)indexOfObjectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))谓词,但是无论如何,NSPredicate 的东西或多或少是为了处理这种类型的事情而设计的,但它们是令人困惑和有限的。基本上,迭代非常快,因为除非大型数据库样式优化,否则过滤抽象通常最终会迭代。 (通过让你构造+销毁+与各种对象的接口来浪费效率)。

As it turns out, NSFastEnumeration (the one where you say for (NSDictionary *playlist in Playlists) is quite, well, fast. See here for details. If for some crazy reason you really don't want to do that, you can use - (NSUInteger)indexOfObjectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate, but that probably iterates over the array anyway. NSPredicate stuff was more or less designed to handle this type of thing, but they are confusing and limited. Basically iterating over things is really fast, because barring large database style optimizations, filtering abstractions usually end up iterating anyway (wasting efficiency by making you construct+destroy+interface with various objects).

甜`诱少女 2024-09-09 08:53:33

请参阅 NSString-propertyList 方法。

see the -propertyList method of NSString.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文