First try at sorting an array - objective-c

I am trying to sort an array by the highest number that I assigned to each entry in the array.
However i don't think it's doing anything.
Any suggestions on where the error may be?
Thanks!
- (NSArray*)sortByPercentage:(NSArray*)array {
NSArray *inputArray = array;
NSSortDescriptor *sortDescriptor = [[ NSSortDescriptor alloc] initWithKey:#"percentMatched" ascending:YES];
//nov 8
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *finalResult = [inputArray sortedArrayUsingDescriptors:sortDescriptors];
[sortDescriptor release];
return [NSArray arrayWithArray:finalResult];
}

I'm intrigued by why your sort doesn't work. This does:
#import <Foundation/Foundation.h>
#interface FooObject : NSObject
#property (nonatomic, assign) NSInteger value;
#property (readonly) NSInteger percentMatched;
#end
#implementation FooObject
#synthesize value;
// compute percentMatched as an elementary function of value
- (NSInteger)percentMatched {
return value * 2;
}
#end
int main(int argc, char *argv[]) {
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
FooObject *foo1 = [[FooObject alloc] init];
foo1.value = 50;
FooObject *foo2 = [[FooObject alloc] init];
foo2.value = 5;
FooObject *foo3 = [[FooObject alloc] init];
foo3.value = 10;
NSArray *myFoos = [NSArray arrayWithObjects:foo1,foo2,foo3,nil];
NSArray *sorters = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"percentMatched" ascending:YES]];
NSArray *mySortedFoos = [myFoos sortedArrayUsingDescriptors:sorters];
for(FooObject *foo in mySortedFoos ) {
printf("%ld ",foo.percentMatched);
}
}
Prints 10 20 100 to the console as expected.

Related

Filter NSArray of Object with NSArray of NSNumber with NSPredicate

i'm trying to filer an array of this Object:
MyObject.h
#interface MyObject : NSObject
#property (assign) int id_object;
#property (nonatomic, strong) NSString *name;
#end
So for example in my firstArray i have some MyObject:
MyObject *ob1 = [[MyObject alloc] init];
[ob1 setId_Object:1;
[ob1 setName:#"Carl"];
MyObject *ob2 = [[MyObject alloc] init];
[ob2 setId_Object:2;
[ob2 setName:#"Carl"];
MyObject *ob3 = [[MyObject alloc] init];
[ob3 setId_Object:3;
[ob3 setName:#"Carl"];
NSArray *firstArray = [[NSArray alloc] initWithObjects:ob1,ob2,ob3,nil];
then i want filter this array with NSPredicate with an array of NSNumber, like this:
NSArray *secondArray = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],[NSNumber numberWithInt:2],nil];
i have tried this:
NSArray *filteredObject = [firstArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"id_object IN %#",secondArray]];
but the filteredObject is empty, how i can do?
Seems to be your test case that is wrong. I don't think your setId_object does what you think it does when calling it with an NSNumber;
[ob1 setId_object:[NSNumber numberWithInt:1]];
NSLog(#"%d", ob1.id_object);
> 391
[ob1 setId_object:1];
NSLog(#"%d", ob1.id_object);
> 1
Replacing the initializations makes your test case run ok.
EDIT: My test case, cut'n'pasted;
MyObject *ob1 = [[MyObject alloc] init]; ob1.id_object = 1; [ob1 setName:#"Carl"];
MyObject *ob2 = [[MyObject alloc] init]; ob2.id_object = 2; [ob2 setName:#"Carl"];
MyObject *ob3 = [[MyObject alloc] init]; ob3.id_object = 3; [ob3 setName:#"Carl"];
NSArray *firstArray = [[NSArray alloc] initWithObjects:ob1,ob2,ob3,nil];
NSArray *secondArray = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],[NSNumber numberWithInt:2],nil];
NSArray *filteredObject = [firstArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"id_object IN %#",secondArray]];
NSLog(#"%#", filteredObject);
>>> <MyObject: 0x100110350> {1,"Carl"}
>>> <MyObject: 0x1001104b0> {2,"Carl"}
once check this one,
NSArray *filteredObject = [questionSections filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"self.Carl contains %# OR self.Carl contains %# ",#"1",#"2"]];
EX:-
NSArray* questionSections=[[NSArray alloc] initWithObjects:[[NSDictionary alloc] initWithObjectsAndKeys:
#"List 3 rooms in your house?",#"name",#"301q.png",#"questionpicture",nil],[[NSDictionary alloc] initWithObjectsAndKeys:#"Name a commonbird?",#"name",#"202q.png",#"questionpicture",nil], nil];
NSArray *filteredObject = [questionSections filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"self.questionpicture contains %# OR self.questionpicture contains %# ",#"2",#"3"]];
NSLog(#"%#",filteredObject);
O/P:--
(
{
name = "List 3 rooms in your house?";
questionpicture = "301q.png";
},
{
name = "Name a common bird?";
questionpicture = "202q.png";
}
)
try replace
#property (nonatomic, copy) NSNumber* id_object;
#property (nonatomic, copy) NSString *name;
instead of
#property (assign) int id_object;
#property (nonatomic, strong) NSString *name;

Access NSMutableArray from another class [duplicate]

This question already has answers here:
Access NSMutableArray from a different class
(3 answers)
Closed 10 years ago.
This is how my Entity classes look:
BaseDataEntity.h
#import -Foundation/Foundation.h
#interface BaseDataEntity : NSObject
#property (assign) NSMutableArray *cbxDataList;
#property (assign) NSString *resaultText;
#end
BaseDataEntity.m
#import "BaseDataEntity.h"
#implementation BaseDataEntity
#synthesize cbxDataList = _cbxDataList;
#synthesize resaultText = _resaultText;
#end
And this is how I try to access them:
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification{
BaseDataEntity *aBaseDataEntity = [[BaseDataEntity alloc] init];
[self setBaseDataEntity:aBaseDataEntity];
}
-(IBAction)ReadPort:(id)sender {
NSMutableArray* array = [[NSMutableArray alloc] init];
for (int i=0; i<10; i++) {
NSString *temp = [NSString stringWithFormat:#"Test %d", i];
[array addObject:temp];
}
[self.baseDataEntity setCbxDataList:array];
NSLog(#" cbxDataList count = %lu",[array count]);
[array release];
[self.baseDataEntity setResaultText:#"Test"];
[self updateUserInterface:TRUE];
}
-(void)updateUserInterface:(BOOL)piClear{
NSString *textValue = [NSString stringWithFormat:#"%#"
,[self.baseDataEntity resaultText]];
if([self.ResaultTextField stringValue] != nil && !piClear){
textValue = [NSString stringWithFormat:#"%#\n%#", textValue
,[self.ResaultTextField stringValue]];
}
NSMutableArray* array = [[NSMutableArray alloc] initWithArray:
[self.baseDataEntity.cbxDataList value]];
for (int i = 0; i < [array count]; i++) {
textValue = [NSString stringWithFormat:#"%#\n%#", textValue
,[array objectAtIndex:i]];
}
[array release];
[self.ResaultTextField setStringValue:textValue];
}
The problem is that I can update resaultText and have access to the value of this. But cbxDataList value is always empty.
You should use retain instead of assign to increase the retain count of cbxDataList.
#property (retain) NSMutableArray *cbxDataList;
Please note, that the object needs to be released sometime, or you could have a memory leak.
In the below function,
-(void)updateUserInterface:(BOOL)piClear
The array creation is wrong.
NSMutableArray* array = [[NSMutableArray alloc] initWithArray:
[self.baseDataEntity.cbxDataList value]];
The above code nneeds to be replaced by,
NSMutableArray* array = [[NSMutableArray alloc] initWithArray:
self.baseDataEntity.cbxDataList];
Try these :
#property (retain) NSMutableArray *cbxDataList;
#property (assign) NSString *resaultText;
And in -(void)applicationDidFinishLaunching:(NSNotification *)aNotification
alloc+init both of them.

Array of floating point values in Objective-C

How can I create array of floating point numbers in Objective-C?
Is it possible?
You can create a dynamic array (size decided at runtime, not compile time) in different ways, depending on the language you wish to use:
Objective-C
NSArray *array = [[NSArray alloc] initWithObjects:
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:2.0f],
[NSNumber numberWithFloat:3.0f],
nil];
...
[array release]; // If you aren't using ARC
or, if you want to change it after creating it, use an NSMutableArray:
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];
[array addObject:[NSNumber numberWithFloat:1.0f]];
[array addObject:[NSNumber numberWithFloat:2.0f]];
[array addObject:[NSNumber numberWithFloat:3.0f]];
...
[array replaceObjectAtIndex:1 withObject:[NSNumber numberWithFloat:99.9f]];
...
[array release]; // If you aren't using ARC
Or using the new-ish Objective-C literals syntax:
NSArray *array = #[ #1.0f, #2.0f, #3.0f ];
...
[array release]; // If you aren't using ARC
C
float *array = (float *)malloc(sizeof(float) * 3);
array[0] = 1.0f;
array[1] = 2.0f;
array[2] = 3.0f;
...
free(array);
C++ / Objective-C++
std::vector<float> array;
array[0] = 1.0f;
array[1] = 2.0f;
array[2] = 3.0f;
For an dynamic approach you can use NSNumber object and add it to NSMutableArray, or if you need only static array then use suggestions from comments, or use standard C.
like:
NSMutableArray *yourArray = [NSMutableArray array];
float yourFloat = 5.55;
NSNumber *yourFloatNumber = [NSNumer numberWithFloat:yourFloat];
[yourArray addObject:yourFloatNumber];
and then to retrive:
NSNumber *yourFloatNumber = [yourArray objectAtIndex:0]
float yourFloat = [yourFloatNumber floatValue];
If you are using Xcode 4.4+, you can try this:
NSArray *a = #[ #1.1f, #2.2f, #3.3f];
Here is all new literals of LLVM Compiler 4.0.
How about something like this?
#interface DoubleArray : NSObject
#property(readonly, nonatomic) NSUInteger count;
#property(readonly, nonatomic) double *buffer;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithCount:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (double)valueAtIndex:(NSUInteger)idx;
- (void)setValue:(double)value atIndex:(NSUInteger)idx;
#end
#implementation DoubleArray
- (void)dealloc
{
if (_buffer != 0) {
free(_buffer);
}
}
- (instancetype)initWithCount:(NSUInteger)count
{
self = [super init];
if (self) {
_count = count;
_buffer = calloc(rows * columns, sizeof(double));
}
return self;
}
- (double)valueAtIndex:(NSUInteger)idx
{
return *(_buffer + idx);
}
- (void)setValue:(double)value atIndex:(NSUInteger)idx
{
*(_buffer + idx) = value;
}
#end
It's a basic array. You can extend this with more complex features like appending, indexed removal etc.

How to release object of another class in our class?

I have created two classes (FirstClass and SecondClass) in command line application. I created an object of SecondClass in FirstClass method. Now I want to call that method in main and release the memory allocated to that object. My code is as follows..
#implementation FirstClass
+(NSMutableArray *) addObject{
NSMutableArray *namesArray = [[[NSMutableArray alloc]init] autorelease];
SecondClass *second = [[SecondClass alloc]init];
NSLog(#"Before adding object, count = %ld ",[second retainCount]); //RC = 1
[second setName:#"Mobicule"];
[namesArray addObject:second];
NSLog(#"First object addeded, count = %ld ",[second retainCount]); //RC = 2
[second release];
NSLog(#"After release, count = %ld",[second retainCount]); //RC = 1
return namesArray;
}
#end
I want to make retain count to zero..
And main function is as follows..
int main (int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
// NSLog(#"Hello, World!");
NSMutableArray *arrayMain = [[NSMutableArray alloc]init];
arrayMain = [FirstClass addObject];
for (int i = 0; i<[arrayMain count]; i++) {
NSLog(#"%#",[[arrayMain objectAtIndex:i] name]);
}
NSLog(#"%ld",[arrayMain retainCount]);
}
return 0;
}
I am assuming your synthesised property for name is retain.
+(NSMutableArray *) addObject{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *namesArray = [[NSMutableArray alloc]init];
SecondClass *second = [[[SecondClass alloc]init]autorelease];
NSLog(#"Before adding object, count = %ld ",[second retainCount]); //RC = 1
[second setName:#"Mobicule"]; //implementation will handle the release for you
[namesArray addObject:second];
NSLog(#"First object addeded, count = %ld ",[second retainCount]); //RC = 2
[pool release];
NSLog(#"After pool release, count = %ld",[second retainCount]); //RC=1
return [namesArray autorelease];
}
You should never use -retainCount, because it never tells you anything
useful.
Take a look at When to use -retainCount?

How do I alphabetically sort a custom object field within a NSMutable Array?

I have a custom object like:
#import <Foundation/Foundation.h>
#interface Store : NSObject{
NSString *name;
NSString *address;
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *address;
#end
I have an array of NSMutableArray (storeArray) containing Store objects:
store1 = [[Store alloc] init];
store1.name = #"Walmart";
store1.address = #"walmart address here..";
store2 = [[Store alloc] init];
store2.name = #"Target";
store2.address = #"Target address here..";
store3 = [[Store alloc] init];
store3.name = #"Apple Store";
store3.address = #"Apple store address here..";
//add stores to array
storeArray = [[NSMutableArray alloc] init];
[storeArray addObject:store1];
[storeArray addObject:store2];
[storeArray addObject:store3];
My question is how can I sort the array by the store name? I know I can sort an array alphabetically by using this line:
[nameOfArray sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
How can I apply this to the store name of my Store class?
NSSortDescriptor *sortDescriptor =
[NSSortDescriptor sortDescriptorWithKey:#"name"
ascending:YES
selector:#selector(caseInsensitiveCompare:)];
[nameOfArray sortedArrayUsingDescriptors:#[sortDescriptor]];
Related documentation:
[NSArray sortedArrayUsingDescriptors:]
NSSortDescriptor
Regexident's answer is based on NSArrays, the corresponding in-place sorting for NSMutableArray would be -sortUsingDescriptors:
[storeArray sortUsingDescriptors:
[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"name"
ascending:YES
selector:#selector(caseInsensitiveCompare:)]]];
Now storeArray it-self will be sorted.