I have an non-mutable array that only needs to have numbers. How would I have to initialize this?
I have it like below right now but I'm thinking there has to be a better way. Can we do it like in C++? Something like this int list[5] = {1,2,3,4,5}; would that have any impact on the application?
myArray = [[NSArray alloc] initWithObjects: [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], [NSNumber numberWithInt:3], nil];
Also, if I had a need for an array of arrays with only numbers, how would this look like? I'm new to obj-c and looking around online I've seen conflicting answers.
Not yet, but soon:
http://blog.ablepear.com/2012/02/something-wonderful-new-objective-c.html
Update: The new syntax is:
#[ #(20), #(10) ]
The #[] creates an array, the #(number) makes an NSNumber that can go in the array.
If it is non-mutable and only contains numbers just use the C array directly. There is nothing wrong with using C arrays in Objective-C, and in your case an NSArray is just unneeded overhead.
You could add a category to NSArray:
#implementation NSArray ( ArrayWithInts )
+(NSArray*)arrayWithInts:(const int[])ints count:(size_t)count
{
assert( count > 0 && count < 100 ) ; // just in case
NSNumber * numbers[ count ] ;
for( int index=0; index < count; ++index )
{
numbers[ index ] = [ NSNumber numberWithInt:ints[ index ]] ;
}
return [ NSArray arrayWithObjects:numbers count:count ] ;
}
#end
countof() looks like this:
#define countof(x) (sizeof(x)/sizeof(x[0]))
Use like this:
const int numbers[] = { 20, 10, 5, 2, 1, 0 } ;
NSArray * array = [ NSArray arrayWithInts:numbers count:countof(numbers) ] ) ;
Or you could just use #CRD's suggestion above...
Related
I want to make an array of integers with as little code as possible and pass that array to an objective C method.
I tried the below. sequence starts out as an array and is passed to setLights: but when sequence is looked at in the method (via breakpoint) it is no longer an array.
*EDIT: I didnt want to use an NSArray because an NSArray of integers is so verbose:
Using NSArray:
NSArray *sequence = [[NSArray alloc] initWithObjects: [NSNumber numberWithInt:0], [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], [NSNumber numberWithInt:3], [NSNumber numberWithInt:4],[NSNumber numberWithInt:5],nil];
Using C array:
int sequence[6] = {0,1,2,3,4,5};
What am I doing wrong?
- (IBAction)testLights:(id)sender {
int sequence[6] = {0,1,2,3,4,5};
//int *sequence[0][1][2][3][4][5]; //also tried this
[self setLights:sequence];
}
- (void)setLights:(int *)sequence {
UIImageView *light=[lgtArray objectAtIndex: sequence[0]];
light.alpha = 0;
[UIView animateWithDuration:0.3f
animations:^{
light.alpha = 1;
}completion:nil
];
}
Use this syntax to pass the array:
- (void)setLights:(int[] )sequence
You are running into a bizarre feature of C that has propagated through its variants: the [mostly] equivalence of pointers and arrays.
if you do
int *sequence ;
then you can do
sequence [4] ;
or
*(sequence + 4)
Arrays and points are mostly interchangeable. Arrays in C variants are merely data allocation. Your definition of
- (void)setLights:(int *)sequence
conveys no information array information. You can still access sequence as though it is an array. setLights simply has no intrinsic information as to how many elements sequence has allocated to it.
The problem here is that your usage of the array in setLights needs to match how you have allotted the data.
If you did
sequence [100] = 10 ;
it would be syntactically correct but likely to create an error.
Is verbose only if you want. Use literals instead:
NSArray *sequence = #[#0, #1, #2, #3, #4, #5];
And access to the value like this:
UIImageView *light = lgtArray[[sequence[0] intValue]]];
I'm trying to figure out the best way to sort an NSMutableDictionary. I have a dictionary of Card keys (i.e. aceSpades) that store Card values (i.e. 14). I have then been using an NSMutableArray to shuffle the 52 Card keys into an array called shuffledCards. Finally I make another array from shuffledCards thats takes a portion (15) of shuffledCards and puts them into an array called computerHand.
The new array computerHand is not good enough because I need to be able to connect the Card values with the Card keys. What I really need to do is create a new NSMutableDictionary for computerHand from the array shuffledCards so that I can sort it by Card values and still be able to retrieve the Card keys.
I'm thinking I need something like this, where currentCard is the first card of the shuffedCards array:
if (currentCard == 1) {
[compHandDictionary setObject:[[highCardDictionary
valueForKey:[shuffledCards objectAtIndex:currentCard]] intValue]
forKey:[cardsShuffled objectAtIndex:currentCard]];
}
However this is not allowed because "int" to "id" is not allowed.
There might be a better way but I have not been able to find anything. Any help would be appreciated.
...
I got this to work by modifying jstevenco's answer. I created two arrays and formed a new dictionary for the computer hand of just the 15 cards. Then to sort I used:
NSArray* sortedKeys = [newDict keysSortedByValueUsingComparator: ^(id obj1, id obj2) {
if ([obj1 integerValue] > [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
if ([obj1 integerValue] < [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
}
return (NSComparisonResult)NSOrderedSame;
}];
Thanks all!
You can sort a dictionary's keys using:
NSArray* sortedKeys = [[dict allKeys] sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
If you then want to create a sorted array from this you can use:
NSArray* objects = [dict objectsForKeys:sortedKeys notFoundMarker:[NSNull null]];
Consider using an array of dictionaries, where each dictionary contains the name and value for a given card, for example like so:
NSArray *cards = #[#{#"name" : #"Queen", #"value" : #12},
#{#"name" : #"Jack", #"value" : #11},
#{#"name" : #"Ace", #"value" : #14},
#{#"name" : #"King", #"value" : #13}];
You could then easily sort the cards array as shown below:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"value" ascending:YES];
NSArray *sortedCards = [cards sortedArrayUsingDescriptors:#[sortDescriptor]];
NSLog(#"\n\n%#\n\n", sortedCards);
Output of the NSLog statement above would be as follows:
(
{
name = Jack;
value = 11;
},
{
name = Queen;
value = 12;
},
{
name = King;
value = 13;
},
{
name = Ace;
value = 14;
}
)
To obtain an array of card names, you could then simply send a valueForKey: message to the sorted array of card dictionaries:
NSArray *sortedNames = [sortedCards valueForKey:#"name"];
NSLog(#"\n\n%#\n\n", sortedNames);
The output of the preceding NSLog statement would be:
(
Jack,
Queen,
King,
Ace
)
I have an array like this:
array: (
(
"http://aaa/product/8_1371121323.png",
"http://aaa/product/14_1371123271.png"
),
(
"http://aaa/product/9_1371121377.png"
)
)
and I have to create another array from that one like this
array: (
"http://aaa/product/8_1371121323.png",
"http://aaa/product/14_1371123271.png",
"http://aaa/product/9_1371121377.png"
)
How can I do that? Is it possible to combine all the objects and separate them using some string?
It can be done in a single line if you like key-value coding (KVC). The #unionOfArrays collection operator does exactly what you are looking for.
You may have encountered KVC before in predicates, bindings and similar places, but it can also be called in normal Objective-C code like this:
NSArray *flatArray = [array valueForKeyPath: #"#unionOfArrays.self"];
There are other collection operators in KVC, all prefixed with an # sign, as discussed here.
Sample Code :
NSMutableArray *mainArray = [[NSMutableArray alloc] init];
for (int i = 0; i < bigArray.count ; i++)
{
[mainArray addObjectsFromArray:[bigArray objectAtIndex:i]];
}
NSLog(#"mainArray :: %#",mainArray);
Sample code:
NSArray* arrays = #(#(#"http://aaa/product/8_1371121323.png",#"http://aaa/product/14_1371123271.png"),#(#"http://aaa/product/9_1371121377.png"));
NSMutableArray* flatArray = [NSMutableArray array];
for (NSArray* innerArray in arrays) {
[flatArray addObjectsFromArray:innerArray];
}
NSLog(#"%#",[flatArray componentsJoinedByString:#","]);
NSMutableArray *arr1 = [NSMutableArray arrayWithArray:[initialArray objectAtIndex:0]];
[arr1 addObjectsFromArray:[initialArray objectAtIndex:1]];
Now arr1 contains all the objects
I know there are many topics with similar issues, but I have not been able to find a topic addressing my question.
I want to store a plist of highscores.
Every entry of highscores must have two elements
an NSString* and an int.
I want to store the top 20 high scores (pairs of strings and ints) and do that in a plist.
I start with:
NSMutableArray *arr = [[NSMutableArray alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"Mylist" ofType:#"plist"]];
I want the item 0 of the array to be a dictionary, where I can insert key value pairs of
(string, int)
How do I do that?
You can always call [arr addObject:score];, sort it, and remove the final item until there are 10.
To sort:
[arr sortUsingComparator:^(id firstObject, id secondObject) {
NSDictionary *firstDict = (NSDictionary *)firstObject;
NSDictionary *secondDict = (NSDictionary *)secondObject;
int firstScore = [[firstDict objectForKey:#"score"] intValue];
int secondScore = [[secondDict objectForKey:#"score"] intValue];
return firstScore < secondScore ? NSOrderedAscending : firstScore > secondScore : NSOrderedDescending : NSOrderedSame;
}];
If you want the scores to be the other way around, change the '>' to '<' and vice-versa. To keep the list down to 10:
while ([arr count] > 10) {
[arr removeLastObject];
}
You may have to sort when you load from your plist. For 10 scores the performance hit will be minimal, so I suggest you do it just in case.
Property List Serialization
You will want to make notice of: the mutability option, as your method probably returns immutable arrays...
storing in a plist is done with the writeToFile:... or writeToURL:... methods
[arr insertObject:[NSMutableDictionary dictionary] atIndex:0];
Hi I'm new with the Objective-C and i try to do some try.
I have an NSArray called "values". It is an array of array. It seems like :
["0" = > "aString",6872,5523,0091]
["1" = > "anotherString",4422,1234,0091]
["2" = > "aString",6812,2143,0314] ...
How do I sort the "values" array than the first integer value?
I should use the NSPredicate ?
please help me with some example.
thanks
Something like that with block (assuming that your integer value are NSNumber or some class that can be compared):
NSArray *sortArray = [yourArray sortedArrayUsingComparator: ^(id elt1, id elt2) {
return [[elt1 objectAtIndex:1] compare:[elt2 objectAtIndex:1]];
} ];