I am having a nsmutable array and in that nearly 50 -60 object having different names ,and can i sort this array in alphabetical order (Is it possible, How?)
For a simple sort like this, I like to use sort descriptors.
Suppose you have an mutable array of objects whose class has a name NSString property:
NSSortDescriptor *sort=[NSSortDescriptor sortDescriptorWithKey:#"name" ascending:NO];
[myArray sortUsingDescriptors:[NSArray arrayWithObject:sort]];
Absolutely, you can use sortUsingSelector: for this:
[myArray sortUsingSelector:#selector(compare:)];
If your array has custom objects, then you will need to implement a sorting method on those objects:
#implementation myCustomObject
...
-(NSComparisonResult) compare:(myCustomObject*) other {
return [self.name compare:other.name];
}
#end
TechZen's approach works well, but it would work better if you used NSSortDescriptor's +sortDescriptorWithKey:ascending:selector:, passing "localizedCompare:" as the selector. This way, the sorting is localized to the user's language, which can make a big difference in string comparison.
myArray=[myDict keysSortedByValueUsingSelector:#selector(compare:)];
Simply Worked for me!
Related
I have an array of custom objects which contains a custom object Address with properties street, area, state, country.
I need to get all the the names of the areas from that array so i did some thing like this.
NSMutableArray *areas = [[NSMutableArray alloc]init];
for (Address *item in addresses) {
[areas addObject:item.area];
}
Now areas contain all the names of the area.
Is there any other way to get the all the areas of address items with out looping through the array of addresses (as above), using predicates or some other way.
Well as long as the object is KVC-compliant for the area property then simply:
NSArray *areas = [addresses valueForKey:#"area"];
(If you want areas to be mutable, as per your code, then you'll need to use mutableCopy in the above statement).
See [NSArray valueForKey:]:
Returns an array containing the results of invoking valueForKey: using
key on each of the array's objects.
Also We are using mutableArrayValueForKey: method to get the array of values corresponding to the key
NSMutableArray *areas = [addresses mutableArrayValueForKey:#"name"];
I'm just looking for a nicer and more efficient way to iterate through a given array of objects and compare a NSString property of each to another array just containing NSStrings.
My current code uses two for-each loops but it don't think that it is the most efficient way.
for (MYClass *foo in arrayOfMyClass) {
for (NSString *ID in arrayOfStringIDs) {
if ([foo.Id isEqualToString:ID]) {
//Do something
break;
}
}
}
I think that it should be somehow possible to drop at least one loop with some cool tricks.
If all you want to know is if foo.Id exists in arrayOfStringIDs, use an NSSet of strings instead. Then you can do:
NSSet * mySetOfStringIDs = [NSSet setWithArray:arrayOfStringIDs];
for(MyClass * foo in arrayOfMyClass) {
if([mySetOfStringIDs containsObject:foo.Id]) {
// Do something
break;
}
}
This avoids the second loop, since containsObject: is generally much faster than O(n) for a set. You should, of course, do your own profiling as needed.
Check for indexofobject method of Nsarray. May be it can help you to get the index directly instead of a loop for the string in nsarray.
If you want to get an array of strings that exist in both arrayOfMyClass and arrayOfStringIDs then you could use key-value coding to pull the set of strings out of arrayOfMyClass and intersect the resulting set with arrayOfStringIDs. If your class is KVC compliant then you can get all the Id strings out of it as a set:
NSMutableSet *idSet=[NSMutableSet setWithArray:[arrayOfMyClass
valueForKeyPath:#"#distinctUnionOfObjects.Id"]];
[idSet intersectSet:[NSSet setWithArray:arrayOfStringIDs]];
NSArray *idArray=[idSet allObjects];
Unfortunately there is not a method to intersect two NSArrays which is why they have to be turned into a set first.
So I have an NSArray with custom objects called Church. And in each church there is an array of mass times. So there is a method in church which calculates the closest mass to the user's current time.
-(NSDate *)closestTimeTo:(NSDate *)currentTime
I want to be able to sort the NSArray of Church by the results (which are NSDate) returned by that method for each object. Basically to get a sorted list of masses sorted by the closest time and also location.
I'm using categories and can't store the closest times as properties since its a core data object. I also don't think its a good idea to save those values to core data as these methods will be called constantly due to location services.
Any ideas on how I can sort such array using the result of its objects' method?
Try the following block. It would help directly(or at least with minor modifications).
NSArray *sortedArray;
sortedArray = [yourArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSDate *first = [(Church*)a closestTimeTo:currentTime];
NSDate *second = [(Church*)b closestTimeTo:currentTime];
return [first compare:second];
}];
Make a new method in your class that takes another Church class and returns NSOrderedSame, NSOrderedAscending or NSOrderedDescending, depending on whether you want that object to be first or last. Use your closestTimeTo method to find that out. Then use NSArray's sortedArrayUsingSelector call with your method.
I'm attempting to create an NSArray with a grouping of string literals, however I get the compile error "Initializer element is not constant".
NSArray *currencies = [NSArray arrayWithObjects:#"Dollar", #"Euro", #"Pound", nil];
Could someone point out what I'm doing wrong, and possibly explain the error message?
New syntax for creating an array with string literals:
NSArray *currencies = #[#"Dollar", #"Euro", #"Pound"];
To fix your complication error the code must be in a method. If you want to use it statically then create a class method that follows the singleton pattern.
This isn't a problem with the NSArray creation itself (you would get the same error if you wrote [NSArray array] instead), but with where you've written it. I'm guessing this is a global or file-static NSArray. In C, that kind of variable has to have a constant initializer — meaning not a function call (or, by extension, a method call). The solution is to put the actual creation and assignment of the array into a method that will be called before you need the array, such as initialize.
It sounds like Chuck has spotted the problem. One thing you want to be aware of though in coding your solution is that you'll want to avoid storing an autoreleased instance of NSArray in a static variable. Also, a common pattern for these situations is to write a class method that creates and returns the value stored in the static variable, like so:
+ (NSArray *)currencies
{
static NSArray *_currencies;
// This will only be true the first time the method is called...
//
if (_currencies == nil)
{
_currencies = [[NSArray alloc] initWithObjects:#"Dollar", #"Euro", #"Pound", nil];
}
return _currencies;
}
Although this is old, please notice that Apple committed a new patch to the llvm project adding support for new Objective-C literal syntax for NSArray, NSDictionary and NSNumber.
See here and here
I'm a newbie in objective-c, but I think that the correct code is:
NSArray *currencies = [[NSArray alloc] initWithObjects:#"Dollar", #"Euro", #"Pound", nil];
I am not sure tho.
There's nothing wrong with that code. Are you sure the error is being produced at that line?
So I have a custom class Foo that has a number of members:
#interface Foo : NSObject {
NSString *title;
BOOL taken;
NSDate *dateCreated;
}
And in another class I have an NSMutableArray containing a list of these objects. I would very much like to sort this array based on the dateCreated property; I understand I could write my own sorter for this (iterate the array and rearrange based on the date) but I was wondering if there was a proper Objective-C way of achieving this?
Some sort of sorting mechanism where I can provide the member variable to sort by would be great.
In C++ I used to overload the < = > operators and this allowed me to sort by object, but I have a funny feeling Objective-C might offer a nicer alternative?
Many thanks
That's quite simple to do.
First, in your Foo object, create a method
- (NSComparisonResult) compareWithAnotherFoo:(Foo*) anotherFoo;
Which will return
[[self dateCreated] compare:[anotherFoo dateCreated]];
In the end, call on the array
[yourArray sortUsingSelector:#selector(compareWithAnotherFoo:)];
Hope this helps,
Paul