Sort NSArray in descending order - ios

I have an NSArray with 4 objects, let's say 1, 2, 3 and 4. I want to sort this array in ascending order, but with a randomly selected starting number. For instance; 2, 3, 4 and 1 or 4, 1, 2 and 3.
How can I do this?
What I have thus far:
NSArray *playersArray = [_players allKeys];
NSSortDescriptor *sortPlayerArray = [[NSSortDescriptor alloc] initWithKey:nil ascending:YES];
playersArray = [playersArray sortedArrayUsingDescriptors:#[sortPlayerArray]];
This results in 1, 2, 3, 4, obviously. I am also able to randomly order the players, like so:
activePlayersArray = [_players allKeys];
NSMutableArray *temp = [[NSMutableArray alloc] initWithArray:activePlayersArray];
int count = (int)[temp count];
for (int i = 0; i < count; ++i) {
int nElements = count - i;
int n = (arc4random() % nElements) + i;
[temp exchangeObjectAtIndex:i withObjectAtIndex:n];
}
activePlayersArray = [NSArray arrayWithArray:temp];
So how can I "combine" these two to get the results I want?
Hope you guys can help me.
Thanks!

This is really an algorithm problem, not an iOS problem. Here are the steps to follow
make a note of your randomly selected number
Sort the array in descending order as you normally would (as in Sort an NSArray in Descending Order)
Then split the array at the location of your special number (similar to How to split an NSArray into two equal pieces?)
after the split create a new array where the second piece now comes first
Another solution is to create a circular array of sorted elements and then traverse the array in reverse order.

I think this is what #Konsol intends, with a couple fixes: (1) it looks like the OP wants the order to be ascending, and (2) the array split in the other answer is at the midpoint. But I think the spirit is correct...
// Start with an unsorted (immutable?) input array of numbers (or any object
// that implements compare:.
// Pick a random location and produce an output array as described by the OP
NSMutableArray *mutableArray = [inputArray mutableCopy]; // if its not mutable already
[mutableArray sortUsingSelector:#selector(compare:)];
NSInteger inputIndex=arc4random_uniform(mutableArray.count);
NSArray *start = [mutableArray subarrayWithRange:NSMakeRange(inputIndex, mutableArray.count-inputIndex)];
NSArray *end = [mutableArray subarrayWithRange:NSMakeRange(0, inputIndex)];
NSArray *outputArray = [start arrayByAddingObjectsFromArray:end];
NSLog(#"%#", outputArray);

int count = (int)[activePlayersArray count];
int n = (arc4random() % nElements) + i;
NSMutableArray *temp = [[NSMutableArray alloc] init];
for (int i = 0; i < count; ++i) {
int nElements = count - i;
[temp addObject:[activePlayersArray objectAtIndex:(n-i)%count]];
}
activePlayersArray = [NSArray arrayWithArray:temp];
Hope it works!

Related

Add diagonal of 2 dimensional array in Objective C

Given: 2 dimensional array :
[[1 2 3]
[4 5 6]
[9 8 9 ]]
Need to add diagonal of the array : 1+5+9 = 15
NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableArray arrayWithObjects:#1,#2,#3,nil],
[NSMutableArray arrayWithObjects:#4,#5,#6,nil],
[NSMutableArray arrayWithObjects:#9,#8,#9,nil],nil];
NSNumber* total = 0;
for (NSNumber* row in array) {
total = total + array[row][row];
}
NSLog(#"%#",total);
Here I can't access the element of the array. It gives error on "array[row][row]". What is the best way to initialize a 2D array and access the element of the array in Objective-C?
In your code, what you are doing here: for (NSNumber* row in array) is putting each element of array, inside the row variable (this is called array enumeration btw).
What you need is to use the index of the array - not the value of each element (that's what you are doing above).
Also, you don't have to use an object (NSNumber *) for your calculations. A simple NSInteger will do.
Here's the code:
NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableArray arrayWithObjects:#1,#2,#3,nil],
[NSMutableArray arrayWithObjects:#4,#5,#6,nil],
[NSMutableArray arrayWithObjects:#9,#8,#9,nil],nil];
NSInteger total = 0;
for (NSUInteger row = 0; row < array.count; row ++) {
total = total + [array[row][row] integerValue]; // integerValue converts the NSNumber to an NSInteger
}
NSLog(#"%d",total);

Matching Mutable Array value to index of another Array and getting other Array value at that index

Objective: compare values stored in Mutable array(which are changing constantly) to the index of a static Array. When the values match I would like to add the object(s) of the static array to a new mutable array.
Example:
Values of MutableArray at present state:
(1,2,3)
(Index) - Values of Static Array:
(0) - "Zero"
(1) - "One"
(2) - "Two"
(3) - "Three"
(4) - "Four"
Take values from initial MutableArray and compare them to the static array index's. Output the values at those index's to a new MutableArray
("One","Two","Three")
The initial array is derived by passing the MutableArrayContents for a search via predicate into this:
NSMutableArray *indexArray = [NSMutableArray array];
for (NSMutableArray* obj in _searchResults)
{
if([_questionsArray containsObject:obj] && ![indexArray containsObject:obj])
[indexArray addObject:#([_questionsArray indexOfObject:obj])];
}
IndexArray is the array of "index's".
I've tried for loops but they are not working correctly, any help would be appreciated.
Thanks!
You can try this:
NSArray *staticArr = #[#"Zero",#"One",#"Two",#"Three",#"Four"];
NSArray *otherArr = #[#1,#2,#3];
NSMutableArray * array = [[NSMutableArray alloc] initWithCapacity:[otherArr count]];
for(int i = 0; i < [staticArr count]; i++) {
for(int j = 0; j < [otherArr count]; j++) {
if([[otherArr objectAtIndex:j] intValue] == i) {
[array insertObject:[staticArr objectAtIndex:i] atIndex:j];
break;
}
}
}
Try this method
NSArray *staticArr = #[#"Zero", #"One", #"Two", #"Three", #"Four"];
NSArray *otherArr = #[#(1), #(2), #(3)];
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:[otherArr count]];
[staticArr enumerateObjectsUsingBlock:^(NSString *string, NSUInteger staticIndex, BOOL *staticStop) {
[otherArr enumerateObjectsUsingBlock:^(NSNumber *number, NSUInteger index, BOOL *stop) {
if (number.integerValue == staticIndex) {
[array insertObject:string atIndex:index];
}
}];
}];
I am typing this on a tab. Please forgive any formatting issues
NSMutableArray *indices; //I am omitting the adding of data, it contains required indices as NSNumber objects
NSArray *staticArr = #[#"One", #"Two", #"Three", #"Four", #"Five"];
NSMutableArray *array = [NSMutableArray new];
for(NSNumber *index in indices) {
NSInteger idx = [index integerValue];
If(idx < staticArr.count)
{
[array addObject:[staticArr objectAtIndex:idx];
}
}
This will be in the order of the elements in indices array and may have repetitions in case there are repetitions in indices array.
This is the most straightforward way, there are many ways to get the subarray using Apple's API

Shuffle Randomize an NSMutableArray excepting item at index0

Have an NSMutableArray, and when my users press a button, I'd like all items in the array to randomly change position, !! except for the first !!.
Right now I have
-(void)shufflemyList{
NSLog(#"Un Shuffled array : %#",myList);
NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];
while ([myList count] > 0)
{
int index = arc4random() % [myList count];
id objectToMove = [myList objectAtIndex:index];
[array addObject:objectToMove];
[myList removeObjectAtIndex:index]; }
// test
NSLog(#"Shuffled array : %#",array);
myList=array; }
This works to completely shuffle the list.
Is there a way to shuffle the whole list, excepting the first item?
Just add 2 lines
-(void)shufflemyList{
NSLog(#"Un Shuffled array : %#",myList);
NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];
// new code ---
[array addObject:myList[0]];
[myList removeObjectAtIndex:0];
// ---
while ([myList count] > 0)
{
int index = arc4random() % [myList count];
id objectToMove = [myList objectAtIndex:index];
[array addObject:objectToMove];
[myList removeObjectAtIndex:index]; }
// test
NSLog(#"Shuffled array : %#",array);
myList=array; }
Also it is better to use 'arc4random_uniform(n)' instead of 'arc4random() % n'. From docs:
arc4random_uniform() will return a uniformly distributed random number
less than upper_bound. arc4random_uniform() is recommended over
constructions like ``arc4random() % upper_bound'' as it avoids "modulo
bias" when the upper bound is not a power of two.

Iterating through an NSArray and storing items in groups of 12

I've definitely tried to do my due diligence on this one but keep coming up short. I have an array of objects that I have parsed and I want to iterate through these and store them. Assuming the array is 144 objects (just an example), I want to store it in groups of 12 to display in a tableview cell. Actually of those 12 objects in the array I'll likely only be displaying 3-4 in the cell, but all of those objects in the detail view.
To help explain what I mean (sorry if it hasn't made sense at this point) here's some of the code I've got that is getting the data.
NSMutableArray *objectsArray = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in objectsNode) {
PHSingleEvent *singleEvent = [[PHSingleEvent alloc]init];
[objectsArray addObject:singleEvent];
singleEvent.title = [[element firstChild] content];
}
This pulls down the entire array of objects (an unknown number but definitely a multiple of 12). How would I go about storing 12 objects at a time into a single event?
I can log the info with
PHSingleEvent *firstObject = [objectsArray objectAtIndex:0] // this one is null
PHSingleEvent *eventStartTime = [objectsArray objectAtIndex:1];
PHSingleEvent *eventEndTime = [objectsArray objectAtIndex:2];
...
PHSingleEvent *lastObject = [objectsArray objectAtIndex:11];
NSLog(#"single object of event: %#", eventStartTime.startTime);
NSLog(#"single object of event: %#", eventEndTime.endTime);
etc...
But the array keeps going past 12. I want to iterate up through each 12 objects and store those values, preferably as strings to be displayed in a cell and detail view.
Any ideas?
Thanks much in advance and I will be here to answer any questions if I was unclear.
C.
How about using a for loop? Assuming that each event object has 12 sub-objects (i.e. indices 0 - 11) you could achieve storing it by using a mod function. For example:
NSMutableArray *eventArray = [[NSMutableArray alloc] init];
for(int i=0; i<objectArray.count/12;i++){
int offset = 12*i;
NSMutableArray *event = [objectsArray subarrayWithRange:NSMakeRange(offset, 12)];
[eventArray addObject:event];
}
So now eventArray has n arrays, each of 12 objects (where n = totalObjects/12)
EDIT: A better idea would be to use NSDictionary. For example:
NSMutableArray *eventArray = [[NSMutableArray alloc] init];
for(int i=0; i<objectArray.count/12;i++){
int offset = 12*i;
NSDictionary *tempDict = [[NSDictionary alloc] initWithObjectsAndKeys: [objectsArray objectAtIndex: offset], #"eventStartTime", [objectsArray objectAtIndex: offset+1], #"eventEndTime", ..., [objectsArray objectAtIndex: offset+11, #"lastObject",nil];
[eventArray addObject:tempDict];
}
Then you can access each of the above objects using a similar statement as shown below:
PHSingleEvent *eventStartTime = [[eventArray objectAtIndex: index] objectForKey: #"eventStartTime"];
Hope this helps
This method will return an array of smaller arrays based on the group size you specify.
- (NSMutableArray*)makeGroupsOf:(int)groupSize fromArray:(NSArray*)array
{
if (!array || array.count == 0 || groupSize == 0)
{
return nil;
}
NSMutableArray *bigGroup = [[NSMutableArray alloc] init];
for (int i = 0; i < array.count; )
{
NSMutableArray *smallGroup = [[NSMutableArray alloc] initWithCapacity:groupSize];
for (int j = 0; j < groupSize && i < array.count; j++)
{
[smallGroup addObject:[array objectAtIndex:i]];
i++;
}
[bigGroup addObject:smallGroup];
}
return bigGroup;
}
I haven't tested it or anything though. After you have the big array with the smaller array(s) it is just a matter of filling each cell with any desired number of objects from the sub arrays.
Note: You might want to handle the cases when the array is empty, null or the group size is 0 differently.

iphone : How to make an array with objects from other arrays

I have three NSMutabelArrays, each contain about ten strings, for example:
1stArray = [NSMutableArray arrayWithObjects:#"a",#"b",#"c",#"d",#"e",#"f",#"g",#"h",#"i",nil];
2ndArray = [NSMutableArray arrayWithObjects:#"j",#"k",#"l",#"m",#"n",#"o",#"p",nil];
3rdArray = [NSMutableArray arrayWithObjects:#"q",#"r",#"s",#"t",#"u",#"v",#"w",nil];
Now I want to make a 4th NSMutabelArrays with first 2 objects of those 3 NSMutableArray.
for example I want a 4th array like this:
4thArray = [#"a",#"b",#"j",#"k",#"q",#"r"]
How to achieve this?
I think you are looking for a code like this
int numElements = 2;
int numArrays = 3;
NSMutableArray * 4thArray = [NSMutableArray array];
for (int arrays = 0; arrays < numArrays; arrays++) {
for (int count = 0; count < numElements; count++) {
switch (arrays) {
case 0:
[4thArray addObject:[1stArray objectAtIndex:count]];
break;
case 1:
[4thArray addObject:[2ndArray objectAtIndex:count]];
break;
case 2:
[4thArray addObject:[3rdArray objectAtIndex:count]];
break;
}
}
}
Seems like this would be better solved using an array of arrays, or possibly a combination of arrays and dictionaries, depending on what you're trying to achieve. The answer to your question is trivial, so I'll point you to the NSArray Reference for that, but you probably want to consider a different approach.
do like this
NSMutableArray *firstArray = [NSMutableArray arrayWithObjects:#"a",#"b",#"c",#"d",#"e",#"f",#"g",#"h",#"i",nil];
NSMutableArray *secArray = [NSMutableArray arrayWithObjects:#"j",#"k",#"l",#"m",#"n",#"o",#"p",nil];
NSMutableArray *thrdArray = [NSMutableArray arrayWithObjects:#"q",#"r",#"s",#"t",#"u",#"v",#"w",nil];
NSMutableArray *fourthArr = [[NSMutableArray alloc] initWithObjects:[firstArray objectAtIndex:0],[firstArray objectAtIndex:1], [secArray objectAtIndex:0],[secArray objectAtIndex:1], [thrdArray objectAtIndex:0],[thrdArray objectAtIndex:1],nil];
NSLog(#"%d", fourthArr.count);

Resources