NSArray of int[]

30,080

Solution 1

EDIT: changed to use a less evil method courtesy of Tommy's comment.

You can treat the static arrays as pointers and store them in NSValue objects:

[mutableArray addObject:[NSValue valueWithPointer:lvl1]];

...

int* level = [(NSValue*)[mutableArray objectAtIndex:whatever] pointerValue];
int someContainedInt = level[index];

Alternatively, you could wrap each individual array in its own NSData object and store those in the mutable array:

[mutableArray addObject:[NSData dataWithBytes:lvl1 length:sizeof(int) * lengthOfArray]];

...

const int* level = (const int*) [(NSData*) [mutableArray objectAtIndex:whatever] bytes];

I have to concur with Frank C, though -- why do you need to use a Cocoa array to store these arrays at all? Can't you just treat the whole lot as a 2D C array? If it's static data anyway then the dynamic aspects of NSMutableArray seem pretty much superfluous.

EDIT 2: Using C arrays

If your level arrays are all the same length -- call it LEVEL_SIZE -- you can build a straight 2D array like this:

static int levels[][LEVEL_SIZE] = 
{
    {1, 2, 3, 4, ...},
    {15, 17, 19, 21, ...},
    {8, 7, 6, 5, ...}
};

Otherwise, you'll need to build each array separately and then put them together afterwards:

static int level1[] = {1, 2, 3, 4, ...};
static int level2[] = {15, 17, 19, 21, ...};
static int level3[] = {8, 7, 6, 5, ...};
...
static int* levels[] = {lvl1, lvl2, lvl3, ...};

Either way, you can pluck out one level as a pointer:

int* level = levels[0];
printf("%d\n", level[1]); // should print 2

To start with, you'll have NUM_LEVELS levels -- in your case 50 -- so stick that many indices 0..49 into your mutable array, as NSNumber objects:

NSMutableArray* levelIndices = [NSMutableArray arrayWithCapacity:NUM_LEVELS];
for ( int i = 0; i < NUM_LEVELS; ++i )
    [levelIndices addObject:[NSNumber numberWithInt:i]];

Use this array for your counting, getting and removing needs. When you pull an NSNumber object out, use it to index into the levels array to get the level:

int* level = levels[[someNSNumber intValue]];

Et voila.

Solution 2

Use NSNumber to store int in an NSMutableArray.

Here's sample code :

// Add 
[yourMutableArray addObject:[NSNumber numberWithInt:yourInt]];

// Get 
yourInt = [((NSNumber*)[yourMutableArray objectAtIndex:0]) intValue];

Solution 3

Craig,

As Objective-C is based on C and you can intermix both in iOS or OSX applications why not just create an array of ints?

This would give you the performance of scale and reduction in memory vs. converting everything to NSNumber.

Frank

Solution 4

Box it into a NSNumber :

[array addObject:[NSNumber numberWithInt:5]];
Share:
30,080
Craig White
Author by

Craig White

Updated on July 09, 2022

Comments

  • Craig White
    Craig White almost 2 years

    I am needing to store a heap of int[] for my levels.

    I decided that storing the int[]'s in an NSMutableArray and getting a random one from the array would be a good way to do it.

    Thing is, an int[] is not an object and you cannot add it inside an obj-c array.

    Does anyone have a suggestion on how I can get a random integer array?

    My arrays looks like this:

    int lvl1[] { 4,80,49,6,40,77,21,20,91,5,100,91,...... }; 
    int lvl2[] { 20,260,385,20,290,448,21,210,329,21,...... }; 
    int lvl3[] { 441,21,90,364,21,70,385,21,170,434,...... }; 
    ...
    int lvl50[] { 441,21,90,364,21,70,385,21,170,434,...... }; 
    

    I then need to get a random one of these.

  • Craig White
    Craig White about 13 years
    I thought about this but I will literally have thousands of integers automatically generated. This would be a very messy solution. Also, they are static if it helps.
  • Nyx0uf
    Nyx0uf about 13 years
  • Craig White
    Craig White about 13 years
    Sorry but this doesn't help. My array looks like this: int lvl1[] { 4,80,49,6,40,77,21,20,91,5,100,91,...... } int lvl2[] { 20,260,385,20,290,448,21,210,329,21,...... } int lvl3[] { 441,21,90,364,21,70,385,21,170,434,...... } I then need to get a random one of these
  • Tommy
    Tommy about 13 years
    You can store pointers in objects via NSValue +valueWithPointer: and [instanceOfNSValue pointerValue], no need to make any assumptions about the relative sizes of pointers and integers. But I think the poster wants the individual numbers to be objects without, you know, the cost of them being objects.
  • Craig White
    Craig White about 13 years
    I dont need to necessarily use a NSMutableArray, it's just that they have an easy API of count, objectatindex and add/remove.
  • Craig White
    Craig White about 13 years
    I am using an int[]. I am trying to avoid the use of unneccesarily using multiple converts of NSNumbers and the such. Thanks anyway :)
  • walkytalky
    walkytalky about 13 years
    @Tommy thanks for pointing that out, I've updated the answer accordingly.
  • walkytalky
    walkytalky about 13 years
    @Craig OK, but you could just keep the level indices (wrapped as NSNumber) in the NSMutableArray.
  • Craig White
    Craig White about 13 years
    Thanks for your help guys, so.. How would I do what I need? Having a generated list of numbers by my level editor, and then get a random one of these lists. How would you do it? Also, these number lists are static and dont need changing unless recompiled.
  • Craig White
    Craig White about 13 years
    Thats Great! Thank you very much @walkytalky and @Tommy! Helped me heaps.
  • Chris K
    Chris K about 13 years
    @Craig I'm not suggesting using NSNumber, in fact it's the opposite. A int[] works just fine on it's own.
  • Dan Rosenstark
    Dan Rosenstark about 13 years
    This is the right answer, generally speaking. In most other languages the boxing and unboxing is done automatically, so you don't see it in the code, but the absolutely negligible performance hit is still there. @Benj the link you provide shows that it's 10x slower than using straight C. True. Still, this is premature optimization.