Objective-C literals for NSSet and NSOrderedSet?
Asked Answered
K

2

49

What, if any, NSSet and NSOrderedSet operations can one perform with the new Objective-C collection literals?

For NSArray, NSDictionary, and NSNumber, see here.

FWIW, this Big Nerd Ranch Post says the indexing syntax is supposed to work for NSOrderedSet. But in my tests it does not. And I haven't been able to find anything about creating ordered sets.

Kist answered 13/8, 2012 at 19:15 Comment(0)
R
50

There is no Objective-C literal syntax for NSSet. It doesn't really make sense to use index subscripting to access NSSet elements, although key-based subscripting might. Either by wrapping or subclassing, you could add your own.

(Correction): Originally I had thought NSOrderedSet wasn't supported either, but it turns out that using index subscripting is supported, but there doesn't seem to be a way of initializing an NSOrderedSet with the literal syntax. However, you could use initWithArray: and pass a literal array:

NSMutableOrderedSet* oset = [[NSMutableOrderedSet alloc] initWithArray: 
    @[@"a", @"b", @"c", @"d", @42]];

oset[2] = @3;
NSLog(@"OrderedSet: %@", oset);

Outputs:

OrderedSet: {(
    a,
    b,
    3,
    d,
    42
)}

According to this excellent post by Mike Ash, you can add the methods that are used to support indexed subscripting to your own objects.

- (id)objectAtIndexedSubscript:(NSUInteger)index;
- (void)setObject: (id)obj atIndexedSubscript: (NSUInteger)index;

And similar methods for object-based keying:

- (id)objectForKeyedSubscript: (id)key;
- (void)setObject: (id)obj forKeyedSubscript: (id)key;

Thus you could implement a wrapper (or with a bit more work, subclass it) around an NSSet and provide key-based retrieval. Cool!

Reprieve answered 6/12, 2012 at 5:30 Comment(1)
From @Almo: NSSet *aset = [NSSet setWithArray:@[@"a", @"b", @"c", @"d", @42]];Villenage
F
43

What about trying this, in case of NSSet:

#define $(...)  [NSSet setWithObjects:__VA_ARGS__, nil]

And using it like this:

NSSet *addresses = $(addr1,addr2,addr3,addr4);

;-)

Fantasize answered 2/3, 2013 at 10:0 Comment(4)
I would prefer [NSSet setWithArray:@[__VA_ARGS__]] so that it will fail when there's a nil element instead of silently stopping earlyDidymous
Both this answer and the comment above are awesome. Be careful if Apple ever implements the $(...) literal format though.Apologetics
To safeguard against future implementation of $(...) literal, just use: #define set() [NSSet setWithArray:@[__VA_ARGS__]]Woodchuck
#define macros can be hard bugs to find since there will be no symbols generated for the expression.Salena

© 2022 - 2024 — McMap. All rights reserved.