Randomly select x amount of items in a "list" - objective-c

I would like to select x amount of items randomly from a "list" in objective C store them in an other "list" (each item can only be selected one) , I'm talking about lists because I'm coming from Python. What would be the best way to store a list of strings in Objective C ?
cheers,

You should use NSMutableArray class for changeable arrays or NSArray for non-changeable ones.
UPDATE: a piece of code for selecting a number of items from an array randomly:
NSMutableArray *sourceArray = [NSMutableArray array];
NSMutableArray *newArray = [NSMutableArray array];
int sourceCount = 10;
//fill sourceArray with some elements
for(int i = 0; i < sourceCount; i++) {
[sourceArray addObject:[NSString stringWithFormat:#"Element %d", i+1]];
}
//and the magic begins here :)
int newArrayCount = 5;
NSMutableIndexSet *randomIndexes = [NSMutableIndexSet indexSet]; //to trace new random indexes
for (int i = 0; i < newArrayCount; i++) {
int newRandomIndex = arc4random() % sourceCount;
int j = 0; //use j in order to not rich infinite cycle
//tracing that all new indeces are unique
while ([randomIndexes containsIndex:newRandomIndex] || j >= newArrayCount) {
newRandomIndex = arc4random() % sourceCount;
j++;
}
if (j >= newArrayCount) {
break;
}
[randomIndexes addIndex:newRandomIndex];
[newArray addObject:[sourceArray objectAtIndex:newRandomIndex]];
}
NSLog(#"OLD: %#", sourceArray);
NSLog(#"NEW: %#", newArray);

Related

Find adjacent boxes to a box in a 4x4 grid

I've an array with 1 to 16 numbers self.gridArray = [[NSMutableArray alloc]initWithObjects:#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16", nil];
I am using this function to randomize or shuffle the array items
-(void)randomizeArray:(NSMutableArray *)myArray{
NSUInteger count = [myArray count];
for (NSUInteger i = 0; i < count; ++i)
{
unsigned long int nElements = count - i;
unsigned long int n = (arc4random() % nElements) + i;
[myArray exchangeObjectAtIndex:i withObjectAtIndex:n];
}
NSLog(#"%#",myArray);
}
This function is working perfectly. My question is that suppose it gives me the shuffled array as (9,15,3,5,1,6,7,8,14,13,12,2,16,10,4,11) which I have placed it in a 4x4 grid. Now I want to find the adjacent numbers for lets say 7 they will be 6,3,8,12. How to find them? Another example if I want to find adjacent numbers of 11 they will be 2,4.
Try this:
NSInteger idx = (NSInteger)[myArray indexOfObject:#"11"]; //obtain the index of the target number
NSMutableArray *adjacentNumbers = [[NSMutableArray alloc] init];
if ( idx+4 < 16 ) { [adjacentNumbers addObject:[myArray objectAtIndex:(NSUInteger)(idx+4)]]; } //number below
if ( idx+1 < 16 && (idx%4 != 3) ) { [adjacentNumbers addObject:[myArray objectAtIndex:(NSUInteger)(idx+1)]]; } //number on the right
if ( idx-4 >= 0 ) { [adjacentNumbers addObject:[myArray objectAtIndex:(NSUInteger)(idx-4)]]; } //number above
if ( idx-1 >= 0 && (idx%4 != 0) ) { [adjacentNumbers addObject:[myArray objectAtIndex:(NSUInteger)(idx-1)]]; } //number on the left

Iterate through nested arrays to grab the first object of each array, then the second, etc

I have nested Arrays,
For example:
[[1,2,3,4,5], [A,B,C,D,E], [Z,Y,X,W,V]
I want to iterate through this array and create a new array, that looks like this:
[1,A,Z,2,B,Y,3,C,X,4,D,W,5,E,V]
I was initially thinking of using nested For loops, e.g.:
int index = 0;
int stop = [[arrays objectAtIndex:0] count];
NSMutableArray* finalArray = [NSMutableArray new];
while(index < stop)
{
for(id array in images)
{
[finalArray addObject:[array objectAtIndex:index]];
}
index++;
}
What would be the most efficient way of doing this?
I don't believe your code will actually generate what you mean (it won't actually compile because NSArray doesn't have addObject:). What you want is a Zipper:
NSArray *Zip(NSArray *arrays) {
if ([arrays count] == 0) {
return #[];
}
NSMutableArray *result = [NSMutableArray new];
NSInteger minCount = NSIntegerMax;
for (NSArray *array in arrays) {
minCount = MIN(minCount, [array count]);
}
for (NSInteger i = 0; i < minCount; i++) {
for (NSArray *array in arrays) {
[result addObject:array[i]];
}
}
return result;
}
Can't comment as I don't have 50 rep, so has to be as an answer!
Have you tried using loops such as
Dim i As Integer, j As Integer
For i = 1 To 5
For j = 1 To 3
Select Item i from array j
Next j
Next i

NSArray not removing objects

I have 5 objects in Array and want to delete 2 in loop but I have a small minor problem in below code
NSMutableArray *totalPages = [[NSMutableArray alloc] init];
[totalPages addObject:#"Test1"];
[totalPages addObject:#"Test2"];
[totalPages addObject:#"Test3"];
[totalPages addObject:#"Test4"];
[totalPages addObject:#"Test5"];
int currentPage = 2;
for (int x = 0; x < [totalPages count]; x++) {
//int pageIds = [[totalPages objectAtIndex:x] intValue];
//NSLog(#"%d",pageIds);
NSLog(#"Array Count %d", (int)[totalPages count]);
NSLog(#"Current Page %d", currentPage);
NSLog(#"Current Iterator Value %d", x);
if (x > currentPage) {
[totalPages removeObjectAtIndex:x];
NSLog(#"Array Count %d", (int)[totalPages count]);
NSLog(#"Number of Pages to be removed %d", x);
}
}
As I want to delete "Test4" and "Test5" but my above code is deleting only "Test5" and if I keep this logic as
if (x >= currentPage)
so it deletes my "Test4" and "Test5" objects but logic fails when int currentPage = 0; so what is the recommended approach to delete Test4 and Test5 as objects in arrays are dynamically added and when currentPage = 0; so Arrays has only 1 Object in it as a pages.
The array is changing as you deleting elements from it, it is getting shortened.
Adjust your for statement and count backwards, that should solve the problem for you.

NSMutableArray with random strings

How can I get 5 random strings in array? I tried this:
stringsArray = [[NSMutableArray alloc]init];
int string_lenght = 10;
NSString *symbols = #"ABCDEFGHIJKLMNOPQRSTUWXYZabcdefghijklmnopqrstuvwxyz";
NSMutableString *randomString = [NSMutableString stringWithCapacity:string_lenght];
for (int y = 0; y<5; y++) {
for (int i = 0; i<string_lenght; i++) {
[randomString appendFormat:#"%C", [symbols characterAtIndex:random()%[symbols length]]];
}
stringsArray = [NSMutableArray arrayWithObject:randomString];
}
But after I run this, all I have is one long random string!
You almost had it. I think this should work, but I haven't tested it.
stringsArray = [[NSMutableArray alloc] init];
int string_length = 10;
NSString *symbols = #"ABCDEFGHIJKLMNOPQRSTUWXYZabcdefghijklmnopqrstuvwxyz";
for (int y = 0; y < 5; y++)
{
//Allocate a new "randomString" object each time, or you'll just add to the old one
NSMutableString *randomString = [NSMutableString stringWithCapacity:string_length];
for (int i = 0; i < string_length; i++)
{
char c = [symbols characterAtIndex:random() % [symbols length]];
[randomString appendFormat:#"%c", c];
}
//Add the object to the array instead of replacing the entire array
[stringsArray addObject:randomString];
}
you are setting the strings array each time, change
stringsArray = [NSMutableArray arrayWithObject:randomString];
to
[stringsArray addObject:randomString];
and you should move the randomString initialisation into the for loop, or you will be appending new random characters to the same string

Array - find how many times an object repeats consecutively

My array objects are as follows:
10,10,10
20,23,14
10,10,10
10,10,10
10,10,10
32,23,42
32,23,42
10,10,10
32,23,23
32,23,23
How can I go through this array and find out how many times the same object repeats sequentially, then add a , and the number of times it repeats?
Then save a new array with objects like:
10,10,10,1
20,23,14,1
10,10,10,3
32,23,42,2
10,10,10,1
32,23,23,2
Any help would be appreciated.
Thanks!
Try this:
NSMutableArray *outArray = [[NSMutableArray alloc] init];
for (NSUInteger j = 0; j < [theArray count]; j++) {
id object = [theArray objectAtIndex:j];
NSUInteger repeats = 1;
while (j + 1 < [theArray count] && [[theArray objectAtIndex:j + 1] isEqual:object]) {
j++;
repeats++;
}
[outArray addObject:object];
[outArray addObject:[NSNumber numberWithUnsignedInteger:repeats]];
}
return outArray;
This can also be done in place if the input array is mutable. I leave that as an exercise for the reader.
Break up every three integers into its own array (make sure they are strings).
Then iterate through each one of those arrays, and input into an NSMutableDictionary, the key is the string (your number), the value is a counter (if seen once, add 1, etc...)
Keep a pointer to the highest key (if newCount > highestCountPointer, then highestCountPointer=newCount)
At the end of that iteration, add the number that the highestCountPoints to to the end of the array.
I'm not an Objective C programmer, so please pardon any language gaffes. Something like the following should do the job:
NSMutableArray *result = [[NSMutableArray alloc] init];
id pending = nil;
NSUInteger count = 0;
for (NSUInteger i = 0; i < [theArray count]; i++) {
id object = [theArray objectAtIndex:i];
if ([object isEqual:pending]) {
count++;
} else {
if (pending != nil) {
[result addObject:[NSString stringWithFormat:#"%#,%d", pending, count]];
}
pending = object;
count = 1;
}
}
if (pending != nil) {
[result addObject:[NSString stringWithFormat:#"%#,%d", pending, count]];
}
Just run "uniq -c" from command line :)