Is there a literal syntax for mutable collections?
Solution 1
No. Just as how there isn't a syntax for creating an NSMutableString
either. Mutable objects are not particularly suited to literal values.
Solution 2
There isn't a built in way, but I just usually use mutableCopy
like this:
NSMutableArray *array = [@[ @"1", @"2", @"3" ] mutableCopy];
Solution 3
But, is there a literal syntax for creating an NSMutableArray or an NSMutableDictionary?
No. Best alternative:
[@[ @"foo", @"bar"] mutableCopy]
Solution 4
Yes. But not quite. Take a look at this;
NSMutableArray *list = [@[] mutableCopy];
This creates a non-mutable array @[]
and calls mutableCopy
which returns a NSMutableArray *
. In place of @[]
, you can give any array literal.
Solution 5
If you have a nested literal of arrays and dictionaries, you can turn this into a fully mutable version by going through NSJSONSerialization
. For example:
NSArray* array = @[ @{ @"call" : @{ @"devices" : @[ @"$(devices)" ] } } ];
NSData* data = [NSJSONSerialization dataWithJSONObject:array
options:0
error:nil];
NSJSONReadingOptions options = NSJSONReadingMutableContainers |
NSJSONReadingMutableLeaves;
NSMutableArray* mutableArray = [NSJSONSerialization JSONObjectWithData:data
options:options
error:nil];
It's a bit of a detour, but at least you don't have to write out the code yourself. And the good thing is that NSJSONSerialization
is very fast.
ma11hew28
Updated on June 15, 2022Comments
-
ma11hew28 almost 2 years
I know I can create an
NSArray
with@[@"foo", @"bar"]
or anNSDictionary
with@{@0 : @"foo", @1 : @"bar"}
.Is there a literal syntax for creating an
NSMutableArray
or anNSMutableDictionary
?-
serge-k about 8 yearsJust don't forget that its
NSDictionary *dictionary = @{@"key" : @"value"};
, might be confusing with he way you have it written. Different from:objectsWithKeys
.
-
-
jscs over 11 yearsHave to disagree with that last sentence. Programming in Python, for example, collections are created literally and mutable by default. It can be very handy.
-
Lily Ballard over 11 years@JoshCaswell: Does python even have immutable collections?
-
jscs over 11 yearsYes, there's things called "tuples" which are immutable.
> (1, 2, 3) # tuple (immutable array)
> [1, 2, 3] # list (mutable array)
-
ma11hew28 over 11 yearsThis seems less efficient and not much shorter than
[NSMutableArray arrayWithObjects:@"1", @"2", @"3", nil]
. -
Marchy over 11 yearsOr alternatively: "NSMutableArray *array = [NSMutableArray arrayWithArray:@[ @"1", @"2", @"3" ]];" - though I like your example better :)
-
meaning-matters about 11 yearsThere is a builtin way in
NSJSONSerialization
. -
danielbeard about 11 years@meaning-matters that is definitely not a literal syntax.
-
Nate Symer almost 11 yearsUh dude, JSONKit is faster. By 5x. Plus, this is too circuitous. Just use -mutableCopy, then you can optionally use -autorelease.
-
meaning-matters almost 11 years@NathanielSymer Come on dude: The two year old JSONKit readme --well maintained stuff btw-- itself says it was just 25% - 40% faster. And
-mutableCopy
only does a shallow copy. The only way is to do something 'circuitous'. -
Mark Amery almost 11 yearsGot to agree with @MattDiPasquale's comment; this is barely shorter than
NSMutableArray arrayWithObjects:...
, is presumably less efficient for what little it matters, and - to my eye - slightly less readable too. A concise literal syntax would've been nice, but if this is the nearest thing to it, then I think I'll stick to the less hacky-feelingarrayWithObjects
for initialising mutable arrays. -
danielbeard almost 11 years@MarkAmery How is that less hacky? The literal syntax expands to
+[NSArray arrayWithObjects:count:]
, notarrayWithObjects
so the literal syntax validates that all items are non-nil. -
Mark Amery almost 11 years@danielbeard Creating an unnecessary intermediate object and then taking a copy of it just to save a few characters compared to directly creating the
NSMutableArray
with one of its own initialiser methods is what feels hacky to me. -
kritzikratzi about 10 yearsyou could also just do this: [[NSMutableArray alloc] initWithArray:@[@"A",@"B"]]. sorry for the downvote, but serializing and deserializing is insane and won't work with many types of objects.
-
meaning-matters about 10 years@kritzikratzi First, insane? You're taking a very simple example, not my example. Please write out
@[ @{ @"call" : @{ @"devices" : @[ @"$(devices)" ] } } ]
and you'll see how insane that is. Second, this works for the types given in @MattDiPasquale's and my example. Even more, I explicitly mention that this works for literals. So please don't apologise! -
ecotax over 9 yearsAs meaning-matters commented on his own NSJSONSerialization reply, mutableCopy only makes a shallow copy. That may be sufficient, but if not his NSJSONSerialization solution is the only general one so far.
-
Matt Mc over 9 yearsYou can also do
NSMutableArray *array = @[].mutableCopy;
which seems more readable. -
maninvan over 8 yearsas posted below you do the following
NSMutableArray *list = [@[] mutableCopy];
i.e. you add mutableCopy at the end. That is how the literal is specified -
Lily Ballard over 8 years@maninvan That's not a literal. That's an expression that uses a literal.
-
maninvan over 8 yearsYou are correct in semantics. But from what happens from the programming perspective is that the expression is how you initialize a mutable object with some data in a short form syntax. The compiler will optimize this so it's probably reduced cpu instructions and memory copies. And it's less to write. It's more succinct. Which is what is desired. The answer 'no' is technically correct but not as helpful as showing the expression.
-
Lily Ballard over 8 years@maninvan No, the compiler does not optimize that. Obj-C does not allow the compiler to optimize that. It's required to construct an immutable array from the literal, and then invoke
mutableCopy
on the result. The expression[@[] mutableCopy]
simply cannot be called a literal. Even if it was optimized, it's still not a literal. -
Kevin about 8 years@KevinBallard You are correct, but I get his point. Using literal syntax and adding mutableCopy to the end looks better than most alternatives and is easy to type. It's not an answer to OP's question, but it can be a solution to OP's problem.
-
Johnny Rockex about 7 yearsDo you know of any issues arising from using this in lieu of the longhand?
-
Dan Rosenstark over 2 years@JohnnyRockex there are no issues with this syntax, but it's pretty ugly if the array is empty to start with ;)
-
Johnny Rockex over 2 yearsI love me some shorthand was just wondering if had a (technical) effect