NSDictionary with ordered keys

2019-01-01 03:51发布

I have an NSDictionary (stored in a plist) that I'm basically using as an associative array (strings as keys and values). I want to use the array of keys as part of my application, but I'd like them to be in a specific order (not really an order that I can write an algorithm to sort them into). I could always store a separate array of the keys, but that seems kind of kludgey because I'd always have to update the keys of the dictionary as well as the values of the array, and make sure they always correspond. Currently I just use [myDictionary allKeys], but obviously this returns them in an arbitrary, non-guaranteed order. Is there a data structure in Objective-C that I'm missing? Does anyone have any suggestions on how to more elegantly do this?

9条回答
泛滥B
2楼-- · 2019-01-01 04:27

I'm late to the game with an actual answer, but you might be interested to investigate CHOrderedDictionary. It's a subclass of NSMutableDictionary which encapsulates another structure for maintaining key ordering. (It's part of CHDataStructures.framework.) I find it to be more convenient than managing a dictionary and array separately.

Disclosure: This is open-source code which I wrote. Just hoping it may be useful to others facing this problem.

查看更多
姐姐魅力值爆表
3楼-- · 2019-01-01 04:27

I don’t like C++ very much, but one solution that I see myself using more and more is to use Objective-C++ and std::map from the Standard Template Library. It is a dictionary whose keys are automatically sorted on insertion. It works surprisingly well with either scalar types or Objective-C objects both as keys and as values.

If you need to include an array as a value, just use std::vector instead of NSArray.

One caveat is that you might want to provide your own insert_or_assign function, unless you can use C++17 (see this answer). Also, you need to typedef your types to prevent certain build errors. Once you figure out how to use std::map, iterators etc., it is pretty straightforward and fast.

查看更多
何处买醉
4楼-- · 2019-01-01 04:33

There is no such inbuilt method from which you can acquire this. But a simple logic work for you. You can simply add few numeric text in front of each key while you prepare the dictionary. Like

NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:
                       @"01.Created",@"cre",
                       @"02.Being Assigned",@"bea",
                       @"03.Rejected",@"rej",
                       @"04.Assigned",@"ass",
                       @"05.Scheduled",@"sch",
                       @"06.En Route",@"inr",
                       @"07.On Job Site",@"ojs",
                       @"08.In Progress",@"inp",
                       @"09.On Hold",@"onh",
                       @"10.Completed",@"com",
                       @"11.Closed",@"clo",
                       @"12.Cancelled", @"can",
                       nil]; 

Now if you can use sortingArrayUsingSelector while getting all keys in the same order as you place.

NSArray *arr =  [[dict allKeys] sortedArrayUsingSelector:@selector(localizedStandardCompare:)];

At the place where you want to display keys in UIView, just chop off the front 3 character.

查看更多
登录 后发表回答