How to get strings with specific length from NSArray? - objective-c

I want to get strings that have specific length in NSArray.
The array has many elements and I don't want to use fast enumeration.
Is there a possible way?

This works like a charm:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.length == %d", lenght];
NSArray *filtered = [array filteredArrayUsingPredicate:predicate];

No matter what you do you will be using fast enumeration whether you realize it or not. However, have you considered using an NSPredicate object and the filteredArrayWithPredicate method?

NSArray *yourArray = [[NSArray alloc] initWithObjects:#"Apple, Orange, Grapes, Cherry, nil"];
for(NSString *element in yourArray){
if(element.length==yourLength){
[filteredArray addObject:element];
}
}
NSLog(#"Filtered array now contains the elements with length %d", yourLength);
NSLog(#"Filtered array--%#", filteredArray);

Related

Removing elements with same value from NSMutableArray

My NSMutableArray contains some strings as elements. One of the element is repeated many times at different indexes in the array. For example [#"", #"1,2,3",#"",#"5,3,2,1",#""].
I want to remove all the elements with value #"" from the mutable array. I tried following ways but couldn't get the solution.
Using For loop:
for(id obj in myMutableArray)
{
if([obj isEqualToString:#""])
{
[myMytableArray removeObject:obj];
}
}
Using dummy mutable array called nextMutableArray
for(id obj in myMutableArray)
{
if([obj isEqualToString:#""])
{
continue;
}
else [nextMutableArray addObject:obj];
}
In both the ways, elements (#"") at other indexes are removed but not at the index 0 (first object). What could be the possible reason? Is there any way to remove all the elements that contain string #"" from the mutable array?
one option is to filter your array using predicates:
NSArray *someArray = #[#"", #"1,2,3", #"", #"5,3,2,1", #""];
NSLog(#"%#", someArray);
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF != ''"];
NSArray *filteredArray = [someArray filteredArrayUsingPredicate:predicate];
NSLog(#"%#", filteredArray);
No Need of For loop. Simply use this.
[mutableArray removeObjectIdenticalTo:#""];
If you want to remove duplicate entries from an array, You can use NSSet Class.
NSSet did not accept duplicate/s value.
NSMutableArray *arrTest=[[NSMutableArray alloc]initWithObjects:#"", #"1,2,3",#"",#"5,3,2,1",#"", nil];
NSSet *set = [NSSet setWithArray:arrTest];
arrTest = [[set allObjects] mutableCopy];
or
You can do like this:
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id str, NSDictionary *unused) { return ![str isEqualToString:#""]; }];
arrTest = [[arrTest filteredArrayUsingPredicate:predicate]mutableCopy];
This is fast and simple way.

NSPredicate, search in a NSArray, inside a NSArray of NSDict

I have a NSArray of NSDictionary.
One of the keys of the NSDictionary contains a NSArray of strings.
Is there a way that I can use NSPredicate to find a specific strins in that Array of strings?
Thanks :)
Also: This work great, but not for sublevelArray
predicate = [NSPredicate predicateWithFormat:#" %K LIKE[cd] %#", sKey, sLookForString];
Just replace LIKE with CONTAINS in your format string. For example, given this array:
NSArray *dogs = #[#{#"name" : #"Fido",
#"toys" : #[#"Ball", #"Kong"]},
#{#"name" : #"Rover",
#"toys" : #[#"Ball", #"Rope"]},
#{#"name" : #"Spot",
#"toys" : #[#"Rope", #"Kong"]}];
...the following predicate can be used obtain a filtered array containing only the dictionaries where the value for the key toy is an array that contains the string Kong.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K CONTAINS[cd] %#", #"toys", #"Kong"];
On NSArray you can use filteredArrayUsingPredicate:, on NSDictionary use enumerateKeysAndObjectsUsingBlock: and then for each value do either a filteredArrayUsingPredicate: if it is an NSArray or you can use evaluateWithObject: using the predicate itself.
If you want to filter the array of dictionaries based on the array of strings, you can use -predicateWithBlock to filter the array, as shown in the code below:
- (NSArray *)filterArray:(NSArray *)array WithSearchString:(NSString *)searchString {
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
NSDictionary *dictionary = (NSDictionary *)evaluatedObject;
NSArray *strings = [dictionary objectForKey:#"strings"];
return [strings containsObject:searchString];
}];
return [array filteredArrayUsingPredicate:predicate];
}

Sorting results in Obj-c

I need to be able to sort the results of my sort method, but it's unclear to me how to do that, do I need to just run a simular method again on the previous results or can it be done in one method?
Here's my method
-(NSArray*)getGameTemplateObjectOfType:(NSString *) type
{
NSArray *sortedArray;
if(editorMode == YES)
{
sortedArray = kingdomTemplateObjects;
}
else
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"type CONTAINS[cd] %#", type];
NSArray *newArray = [kingdomTemplateObjects filteredArrayUsingPredicate:predicate];
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:type
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
sortedArray = [newArray sortedArrayUsingDescriptors:sortDescriptors];
}
return sortedArray;
}
type is being set to "Building" which returns all the building types in my game, but what if I then want those results sorted alphabetically according to their name? or perhaps sorted by which building is the most expensive from it's gold value?
You have to parse the array twice. NSPredicate does not provide a means to sort. Check out the NSPredicate Programming Guide. What I did actually was to quickly scan the NSPredicate BNF Syntax to look for obvious signs of sorting operators, such as ASC or DESC. Nothing is there.
Also, there are a number of similar questions here on SO:
How to sort NSPredicate
NSPredicate Sort Array and Order DESC
NSSortDescriptor and NSPredicate for sorting and filtering
To tell your getGameTemplateObjectOfType: how you want the results sorted, you might pass in some key for sorting. For example:
-(NSArray *)getGameTemplateObjectOfType:(NSString *)type sortedByKey:(NSString *)key ascending:(BOOL)ascending;
But to do so would likely complicate your code - you will have to handle all combinations of key and type inside your function. (Let me know if you don't understand what I'm saying here).
In the end it may be that you resign your filtering function getGameTemplateObjectOfType: to just that: filtering. And if the client of that function wants the results sorted in some fashion, then the client can do so. And then you will discover why it is that Apple has kept the functionalities separated.
in your code, if [kingdomTemplateObjects filteredArrayUsingPredicate:predicate]; returns the correct results
then you can use [newArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]; to sort your array.
-(NSArray*)getGameTemplateObjectOfType:(NSString *) type
{
NSArray *sortedArray;
if(editorMode == YES)
{
sortedArray = kingdomTemplateObjects;
}
else
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"type CONTAINS[cd] %#", type];
NSArray *newArray = [kingdomTemplateObjects filteredArrayUsingPredicate:predicate];
sortedArray = [newArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
return sortedArray;
}

NSArray extract items

I extract data from a NSMutableArray using NSPredicate:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", value];
NSArray *results = [array_to_search filteredArrayUsingPredicate:predicate];
When I use:
NSLog(#"%#", results);
I get:
({pub_id = 102 "pub_name" = "some publisher" city = "Peshawar"});
I would like to extract values of all 3 items pub_id, pub_name, city.
What's being returned is an array containing 1 object (which denoted by the curly braces {} means a dictionary). To extract each of the three components, you can do:
NSString *pub_id = [[results objectAtIndex:0] valueForKey:#"pub_id"];
NSString *pub_name = [[results objectAtIndex:0] valueForKey:#"pub_name"];
NSString *city = [[results objectAtIndex:0] valueForKey:#"city"];
Bear in mind that this solution is only suitable for the example you've provided. If the query ever returns more than 1 object in the array, you'll need to use enumeration/for loop to read the results.
I have understood that you want to get those three objects separately, isn't it?
In case I am right:
NSLog(#"PUBID: %d \n PUBNAME: %# \n CITY: %#", [[results objectAtIndex:0] intValue], [results objectAtIndex:1], [results objectAtIndex:2]);
This code should print
PUBID: 102
PUBNAME: some publisher
CITY: Peshawar.
So your result from
[array_to_search filteredArrayUsingPredicate:predicate];
is another array and you can use that with objectAtIndex:
To get all the values from a dictionary into an array do:
[dictionary allValues];
The object you get out of the array using the prodicate is apparently an NSDictionary. Use the following code:
NSString *city = [[results objectAtIndex:0] valueForKey:#"city"];
et cetera.

How to sort NSPredicate

I am trying to sort my array while using NSPredicate.. I have read other places that possibly using NSSortDescriptor could be an option. Having some trouble figuring this out.
I am attempting to sort my array by companyName.
Any advice appreciated, thanks
Greg
- (void)filterSummaries:(NSMutableArray *)all byNameThenBooth:(NSString*) text results:(NSMutableArray *)results
{
[results removeAllObjects];
if ((nil != text) && (0 < [text length])) {
if ((all != nil) && (0 < [all count])) {
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"companyName contains[cd] %# OR boothNumber beginswith %#", text, text];
[results addObjectsFromArray:[all filteredArrayUsingPredicate:predicate]];
}
}
else {
[results addObjectsFromArray:all];
}
}
you have several options how to sort an array:
I'll show a NSSortDescriptor-based approach here.
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"companyName contains[cd] %# OR boothNumber beginswith %#",
text,
text];
// commented out old starting point :)
//[results addObjectsFromArray:[all filteredArrayUsingPredicate:predicate]];
// create a descriptor
// this assumes that the results are Key-Value-accessible
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:#"companyName"
ascending:YES];
//
NSArray *results = [[all filteredArrayUsingPredicate:predicate]
sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];
// the results var points to a NSArray object which contents are sorted ascending by companyName key
This should do your job.
The filteredArrayUsingPredicate: function walks through your array and copies all objects that match the predicate into a new array and returns it. It does not provide any sorting whatsoever. It's more of a search.
Use the sorting functions of NSArray, namely sortedArrayUsingComparator:, sortedArrayUsingDescriptors:, sortedArrayUsingFunction:context: and the like, whichever serves you most.
Checkout NSArray Class Reference for details.
BTW: If you want to sort lexically, you may use sortedArrayUsingSelector:#selector(compare:) which will use NSString's compare: function to find the right order.