iOS, sorting through two arrays with different counts simultaneously - ios

I am getting an NSRangeException error when test an array's contents (arrayTwo) inside another array enumeration (arrayOne), if arrayTwo does not have a count equal or greater to arrayOne. What is the most efficient way to do this? Basically I want to grab the object from arrayTwo if it exists, else if there is no object there, just ignore the operation.
int i = 0;
for (Class *arrayOneObject in arrayOne) {
if (arrayTwo[i]!= NULL) {
NSLog(#"array two object found");
}
i++;
}
Edit: According to Hot Lick's suggestion, I did the following, works fine.
int i = 0;
for (Class *arrayOneObject in arrayOne) {
if (arrayTwo.count > i) {
NSLog(#"array two object found");
}
i++;
}

Related

Expected method to read array element not found on object of type NSDictionary*

I know there's a lot of questions like this around, but I think my situation's a tad different.
int i = 0;
while (_data[#"VerticalState%i", i] != nil) {
// do things
i++;
}
For example, one 'level' that has 3 VerticalState properties will be implemented as such: VerticalState0, VerticalState1, VerticalState2.
I want to read in those values using that while loop condition above, and it should stop when i = 3. How can I make the idea of that code above work (with some other configuration obviously). FYI, _data is an NSDictionary* instance variable, already loaded with the plist information.
You appear to want to create a dictionary key from a string format. You need to use NSString stringWithFormat:.
while (_data[[NSString stringWithFormat:#"VerticalState%i", i]] != nil) {
Though it would be better to write the loop like this:
int i = 0;
while (1) {
NSString *key = [NSString stringWithFormat:#"VerticalState%i", i];
id value = _dict[key];
if (value) {
// do things
i++;
} else {
break;
}
}

Compare two hour strings Objective C

I have an string with an hour in it, for example "15:15", and an array of other hours in strings ex: #["15:00","16:00","17:00"] I should compare the single string with the array ones in order to get the ETA in a bus station, I tried this code but it keeps iterating and gives me the last greater value in the array, not the first greater value as I need.
int i = 0;
horaArribada = [[[objects objectAtIndex:0]objectForKey:#"Horaris"]objectAtIndex:i];
while ([hora compare:horaArribada]) {
i++;
if (i >= [[[objects objectAtIndex:0]objectForKey:#"Horaris"]count]) {
break;
}else{
horaArribada = [[[objects objectAtIndex:0]objectForKey:#"Horaris"]objectAtIndex:i];
}
}
self.tfHoraArribada.text = horaArribada;
}
}
Where objects is a query from Parse and hora the single string with an hour in it.
You appear to be doing a lot of extra work to iterate over your array. Instead, try a different format for your loop:
for (NSString *horaArribada in [[objects objectAtIndex:0] objectForKey:#"Horaris"]) {
if ([hora compare:horaArribada] == NSOrderedAscending) {
self.tfHoraArribada.text = horaArribada;
break;
}
}
This assumes that your Horaris array is already sorted such from smallest to largest. Also, the logic will not work for the midnight rollover, so you'll probably want to account for that.

How to go back and get new random int, when int is already in my array?

I generate random ints, put them in NSNumber and save them in my Array. Now how I can say "When the Number already is in my array, go back and get a new Number?"
iD = arc4random() %50;
idnumber = [NSNumber numberWithInt:iD];
if ([idarray containsObject:idnumber])
{
NSLog(#"id is in array");
//go back
}else{
NSLog(#"id is not in array");
[idarray addObject:idnumber];
//do something
}
Thanks for answers and sorry for my bad english.
This is a good use of the do/while loop:
if (idarray.count < 50) {
NSInteger value;
do {
value = arc4random_uniform(50);
} while ([idarray containsObject:#(value)]);
[idarray addObject:#(value)];
}
Also note the use of arc4random_uniform and the use of modern boxing syntax.

How to see if NSArray, created with valueForKey is empty

I got an array:
NSArray *itemsArray = [self.tournamentDetails.groups valueForKey:#"Items"];
Where self.tournamentDetails.groups is an NSArray, build with a JSON string from a webRequest.
Items is sometimes empty and sometimes it contains objects. So i need an if statement to check if its empty or not. I've tried some different things like:
if ([itemsArray count]!=0)
if (!itemsArray || !itemsArray.count)
Problem is that if my Items object from valueForKey is empty then the itemsArray still contains an object looking like this
<__NSArrayI 0x178abef0>(
<__NSArrayI 0x16618c30>(
)
)
When theres items inside my Items object it looks like this:
<__NSArrayI 0x18262b70>(
<__NSCFArray 0x181e3a40>(
{
BirthDate = 19601006T000000;
ClubName = "Silkeborg Ry Golfklub";
ClubShortName = "";
CompletedResultSum = {
Actual = {
Text = 36;
Value = 36;
};
ToPar = {
Text = "";
Value = 0;
};
};
}
)
)
Meaning that [itemsArray count] is always equal to 1 or more, and then it jumps into the if statement when it should not.
Anyone know how i can create an if statement where if itemsArray contains "Items:[]" it will be skipped and if itemsArray contains "Items:[lots of objects]" it will run?
EDIT: Solution is to check up on the first index like this if([[itemsArray objectAtIndex:0] count] != 0) then run code.
Try this:
if(itemsArray && itemsArray.count>0) //be sure that it has value){
for(NSArray *item in itemsArray){
if(item.count > 0){
// you have an NSDictionary. Will process it
}else{
//item.count == 0 : this is an empty NSArray.
}
}
}
more simpler
for (id obj in itemsArray)
{
if([obj isKindOfClass:[NSArray class]])
{
if(obj.count > 0)
{
//your if condition here
}
}
}

How to sort NSSet subset in same order as full set NSArray, using NSPredicate?

My self.allArray contains all my objects. Then self.enabledSet contains a subset of these objects.
To create a sortedEnabledArray I currently do this:
NSArray* enabledArray = [self.enabledSet allObjects];
NSArray* sortedEnabledArray;
sortedEnabledArray = [enabledArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b)
{
int indexA = [self.allArray indexOfObject:a];
int indexB = [self.allArray indexOfObject:b];
if (indexA < indexB)
{
return NSOrderedAscending;
}
else if (indexA > indexB)
{
return NSOrderedDescending;
}
else
{
return NSOrderedSame;
}
}];
but I am wondering if this can't be done in a smarter/shorter way, using an NSPredicate for example. Any ideas?
EDIT:
One idea to shorten is:
int difference = indexA - indexB;
// Convert difference to NSOrderedAscending (-1), NSOrderedSame (0), or NSOrderedDescending (1).
return (difference != 0) ? (difference / abs(difference)) : 0;
It depends on number of items in your set and array, but you can do this way:
NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary* bindings)
{
return [self.enabledSet containsObject:object];
}];
NSArray* sortedEnabledArray = [self.allArray filteredArrayUsingPredicate:predicate];
My suggestion is to use a different approach. There is a companion to NSArray called NSIndexSet (and it's mutable counterpart, NSMutableIndexSet). It is an object that is specifically intended to keep track of subsets of an array that meet a given criteria.
NSArray includes methods like indexesOfObjectsPassingTest (and other variants that include additional parameters.) that let you add the indexes of some members of an array to an index set.
Once you have an index set that represents a subset of your allArray, you could use a method like objectsAtIndexes to get an array of just the selected objects.
Store in NSSet not objects, but indexes from allArray array.

Resources