How to compare various NSArrays in Objective-c? - ios

My code contains four NSArrays, each of which contains two objects which represent XY-Coordinate at any point on the screen. Two or more arrays may contain same set of coordinates. I need to find the coordinate which has highest number of repetition among these four arrays. Can the isEqualTo: method help in this case?

One approach would be to maintain an NSDictionary, use the coordinates in your arrays as keys and then maintain a counter for each coordinate (i.e. key) that you increment whenever you see the same coordinate.
This could look somewhat like this:
NSMutableDictionary *coordinateCount = [[NSMutableDictionary alloc] init];
for (int i = 0; i < coordinates.length; i++) { // do this loop for each of your 4 arrays
Coordinate *c = coordinates[i];
if ([coordinateCount containsKey:c]) {
NSInteger count = [coordinateCount[c] integerValue];
count++;
coordinateCount[c] = #(count);
}
else {
coordinateCount[c] = #(1);
}
}
// now you can retrieve the max count value from all collected values
Note that this code is not tested and has to be adjusted depending on your types and variable names.

Related

Call same method multiple times on different parts of array

I have a method which can only work with an array of maximum 100 objets.
However I have an array with more than 100 objects, how could I call this method multiple times so it will work for arrays which have more than 100 objets?
Let's say I have an array of 264 objects.
I could call the method 3 times like so:
[self doSomething:[arrayWithMoreThan100Objects subarrayWithRange:NSMakeRange(0, 100)];
[self doSomething:[arrayWithMoreThan100Objects subarrayWithRange:NSMakeRange(100, 100)];
[self doSomething:[arrayWithMoreThan100Objects subarrayWithRange:NSMakeRange(200, 64)];
This works fine, however I don't always know the size of the array the method needs to process so calling this manually wont work.
How could I get around this?
Thanks!
Use a loop:
NSInteger increment = 100;
for (NSInteger start = 0; start < arrayWithMoreThan100Objects.count; start += increment) {
NSInteger length = MIN(increment, arrayWithMoreThan100Objects.count - start);
NSRange range = NSMakeRange(start, length);
[self doSomething:[arrayWithMoreThan100Objects subarrayWithRange:range];
}
The value of length is set to either 100 or a smaller value if there are less than 100 objects left in the array.

Why setting labels.text from NSMutableArray does not work?

The following code
NSMutableArray *textLabels = [[NSMutableArray alloc] initWithObjects:cell.textLabel1.text, cell.textLabel2.text, cell.textLabel3.text, cell.textLabel4.text, cell.textLabel5.text, nil];
for (int i=0; i<json.count; ++i)
{
textLabels[i] = [NSString stringWithFormat:#"#%#",[json[i] valueForKey:#"text"]]];
}
write to textLabels array correct string values, but labels on the simulator do not change. Why?
It seems that you think asking the label for its text returns an updatable reference to the label value, but this is not the case. The returned string is an immutable object and your code is simply replacing those values with other immutable values.
To update the labels you should hold references to the labels themselves in an array, then you can index into that array and set the text of each. You don't need to store any of the text in an array.
You can add the labels to an array manually or with an IBOutletCollection depending on what your UI definition is.

Randomizing object values without duplication

I'm creating a game with SpriteKit. I have 8 different colored balls positioned at 8 different designated CGPoints on the screen. Once the user gets to a certain score, I would like to randomize the colors of the balls to all be different colors, but I would like to get this result without any of the colors and types duplicating.
I added the balls as objects to a global NSMutableArray and set up a method to enumerate the array. I then wrote an arc4random method to pick a random color type from the array and then apply it to the old ball type. Unfortunately I am getting some duplicates. Does anybody have any suggestions to help me randomize my ball types without duplication?
FYI, I have taken ample time out to read other randomization methods and none of them seem to necessarily answer my question. I am on a deadline. Can somebody please help me?
-(void)ballRotation{
NSLog(#"initial ball list: %#",_ballList);
[_ballList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
int selectedIndex = arc4random() % _ballList.count;
NSLog(#"Selected Index: %i", selectedIndex);
//get a remain list of temp
Ball *newBall = _ballList[idx];
//get the ball at the current _ballList index
Ball *oldBall = _ballList[selectedIndex];
//change the ball in the old position to have the type & texture of the randomly selected ball
oldBall.Type = newBall.Type;
oldBall.texture = newBall.texture;
NSLog(#"new ball list: %lu", newBall.Type);
NSLog(#"new ball list: %#", newBall.texture);
[_ballList removeObjectAtIndex:selectedIndex];
}];
}
Create the array with all the colors. Shuffle it and assign to each ball in order. See Fisher-Yates Shuffle. Here's a category to do it:
#import <Foundation/Foundation.h>
#interface NSMutableArray (KD)
-(void) kd_shuffleArray;
#end
#implementation NSMutableArray (KD)
-(void) kd_shuffleArray {
NSUInteger count = self.count;
for (int i=count-1; i>0; i--) {
int random = arc4random_uniform(i+1);
[self exchangeObjectAtIndex:i withObjectAtIndex:random];
}
}
#end
Oh, and you never want to add/remove to an array while enumerating. It's one of the deadly sins.
Create a mutable array that stores the colors that get selected. Each time you randomize and get a color, compare that color to all the colors stored in the "alreadyChosenColor" array. If the colors are equal, randomize again until it finally does not match a color already existing in the array.
Code:
//Create an array named allColorArray with all colors in it that you will use
bool unique = NO;
while(unique==NO)
{
unique = YES;
//randomIndex is a random int in the range of the allColorArray
randomColor = [allColorArray objectAtIndex:randomIndex]
for(int i=0;i<alreadyChosenColor.count;i++)
{
if([alreadyChosenColor objectAtIndex:i]== randomColor)
unique=false;
}
}
//Set SKSpritenode to use randomColor.
//add randomColor to alreadyChosenColor array.

iPhone - how to select from a collection of UILabels?

I have a few UILabels, any one of which will update according to the index of an NSArray index they represent. I thought of selecting them by their tag
self.displayLabel.tag = myArray[index];
but that changes the tag value to whatever my array is holding at the moment
Using a dictionary for whatever tricks it offers instead of an NSArray doesn't help because i still have to select the correct matching label. This is the effect i want to achieve.
self.|mySelectedLabel|.text = myArray[index];
what should i put in |mySelectedLabel| to get the one i'm looking for?
I'm almost ashamed to ask at my reputation level, but this is stymie-ing me
every search only turns up how to set Labels and change, not the process of selecting
Assuming you have set the tags to the appropriate index to match your
array indices you can use [self.view viewWithTag:index];
Why are you not setting the tag with:
self.displayLabel.tag = index;
Also, you could just loop though an array of labels and find the right one:
for (UILabel *label : labelArray) {
if (label.tag == index) {
label.text = #"I found you!";
}
}
Rather than using tags you can refer to your specific textfields by reference:
// Create an array to hold your textfields
NSMutableArray *textFields = [NSMutableArray array]
// Create your textfields and add them to the array
UITextField *textField;
for (NSUInteger idx = 0: idx++; idx < numberOfTextFieldsYouWant) {
textField = [UITextField alloc] initWithFrame:<whateverYouWant>];
[textFields addObject:textField];
}
Since you are adding the objects to an array, rather than using the tag value 0, 1, 2... you can just access it by it's index in the array
So, for what you want to do you can just do:
textfields[index].text = myArray[index];
It's a lot cleaner, doesn't rely on magic tags, and you have an array of all your dynamic textfields that you can remove, or change in one place.
I think tags are vastly overused, and they aren't necessary in most cases.
Just letting you know I reframed the problem and this eventually worked for me without having to use an array
( with endless experimenting, I sort of bumped into it so I don't know if it constitutes good technique )
the desired label corresponding to the bag weight ( one of a number possible ) displays the right update
- (IBAction)acceptWeight:(UIButton *)sender {
int tempValue = (int) currentWeight;
// current weight comes from a UISegementedController
for (UILabel *labels in self.view.subviews)
{
if (labels.tag == currentWeight)
{
bags[tempValue]++;
labels.text = [NSString stringWithFormat:#"%i",bags[tempValue]];
}
}
totalKilo = totalKilo + (int)currentWeight;
self.totalKilo.text = [NSString stringWithFormat:#"%d",totalKilo];
}

uitableview ios: sorting array based on calculated distance not part of the array

I have an array of points on a map.
I populate the array correctly and I make annotations for them on the map. everything is working fine.
I have another tableview with the same array, and in the "subtitle" of the cells, I calculate the distance to user and present. everything working fine.
Now,I want to sort the list in the table view, in other words I want to sort the same array by distance, lowest to highest.
The thing is that the distance is not part of the array. so how can I cross match the distance with the array, so that when I sort the distance, it takes its belonging object in the array with it and sorts the array as well?
I am fairly new to ios but I have managed to release 3 apps now, and this one is the fourth, far more complex and I think I have covered pretty good ground with making the app so far. From the mapview, to the tableview with a search controller and everything. I am only missing the sorting.
I imagine I need to add some tag or property to each object in the array and assign it to each distance in the distance array.
Any suggestions would be appreciated :)
Thanks in advance.
// Assuming you have your points on the map in an NSArray called
// pointsOnMapArray and your distances in distanceArray, create a
// new mutable array to hold both. Note, the "distances" in this
// case are stored as NSStrings. We'll want to convert them to
// doubles before sorting them.
NSMutableArray *newArray = [[NSMutableArray alloc] init];
// Iterate over all of the points, and add a new element to the mutable
// array which is a new array containing a point and its distance. The
// distance is converted from an NSString to an NSNumber containing a
// doubleValue.
int i;
for (i = 0; i < pointsOnMapArray.count; i++) {
NSArray *newItem = [NSArray arrayWithObjects: [pointsOnMapArray objectAtIndex: i], [NSNumber numberWithDouble:[[distanceArray objectAtIndex: i] doubleValue]], nil];
[newArray addObject: newItem];
}
// Now, sort the new array based upon the distance in the second element
// of each array (ie, the distance).
[newArray sortUsingComparator: ^(id obj1, id obj2) {
NSNumber *dist1 = [obj1 objectAtIndex:1];
NSNumber *dist2 = [obj2 objectAtIndex:1];
return [dist1 compare:dist2];
}];
try making a dictionary with distances and elements of array . then by sorting the distances , array elements can be sorted accordingly.
NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
[dict setObject:(array element) forKey:(correspondingDistance)];
Now by sorting the keys , you can sort the elements of your array accordingly.

Resources