storing regexkitlite matches by by the group instead of the occurance - iphone

I'm not sure if there is away to do this but it doesnt hurt to ask i'm using regexkitlite to create a iPhone app. Im specifically using the Regex lib to parse some html. My question is in a regular expression such as #"<a href=([^>]*)>([^>]*) - " each match in between the brackets can be placed in an array using
NSString *regexString = #"<a href=([^>]*)>([^>]*) - ";
NSArray *matchArray = [response arrayOfCaptureComponentsMatchedByRegex:regexString];
This stores the matches as :
Array ( Array(ENTIRE_MATCH1, FIRST_BRACKETS1, SECOND_BRACKETS1),
Array(ENTIRE_MATCH2, FIRST_BRACKETS2, SECOND_BRACKETS2),
Array(ENTIRE_MATCH3, FIRST_BRACKETS3, SECOND_BRACKETS3));
Is there a command that would allow be to capture the matches like this instead?
Array ( Array(ENTIRE_MATCH1, ENTIRE_MATCH2, ENTIRE_MATCH3),
Array(FIRST_BRACKETS1, FIRST_BRACKETS2, FIRST_BRACKETS3),
Array(SECOND_BRACKET1, SECOND_BRACKET2, SECOND_BRACKET3));
I know i could do this fairly easily with a for loops or for each loops but i was wondering if there is a function in the regexkitlite library.
Thanks in Advance,
Zen_Silence

If anyone else needs a function to copy a group to another array this look will do it i'm still looking for a better solution if someone has one.
group = [[NSMutableArray alloc] initWithCapacity:[matchArray count]];
for (int i = 0; i < [matchArray count]; i++) {
NSString *temp = [[matchArray objectAtIndex: i] objectAtIndex: 2];
[group addObject: temp];
}

Related

Counting same letters in a word

I need to count same letters in a word. For example: apple is my word and first I found whether 'a' exists in this letter or not. After that I want to count the number of 'a' in that word but I couldn't do that. This is my code which finds the specific letter;
if([originalString rangeOfString:compareString].location==NSNotFound)
{
NSLog(#"Substring Not Found");
}
else
{
NSLog(#"Substring Found Successfully");
}
originalString is a word which I took from my database randomly. So, how to count?
Thanks for your help.
i have different idea let's try...
NSString *string = #"appple";
int times = [[string componentsSeparatedByString:#"p"] count]-1;
NSLog(#"Counted times: %i", times);
NSString *strComplete = #"Appleeeeeeeeeeeeeee Appleeeeeeeee Aplleeeeeeeeee";
NSString *stringToFind = #"e";
NSArray *arySearch = [strComplete componentsSeparatedByString:stringToFind];
int countTheOccurrences = [arySearch count] - 1;
Output :
countTheOccurrences --- 34
You could just loop over the string once, adding each letter to an NSMutableDictionary (as the key) and keeping a tally of how many times the letter occurs (as the value).
The resulting NSMutableDictionary would hold the number of occurences for each unique letter, whereby you can extract what you like.

Sorting of NSMutableDictionary

Confusing !!!
I have one NSMutableDictionary called tempDict, having keys Freight, Fuel , Discount (and many more) with relevant values.
I am generating two different NSMutableArrays called arrTVBuyCharge and arrTVBuyCost from tempDict using this Code :
[arrTVBuyCharge addObjectsFromArray:[(NSArray *)[tempDict allKeys]]];
[arrTVBuyCost addObjectsFromArray:[(NSArray *)[tempDict allValues]]];
Problem : I want Freight, Fuel and Discount at the Top in the above arrays in same order (Ofcourse , with Ordering of Values).
What is the Optimum way to achieve this ?
It seems tricky at first, but it's simple when you think about it. All you want to do is get a sorted list of keys, and look up the value for each key as you add them to your arrays.
To get an array with the list of sorted keys:
NSArray *sortedKeys = [[tempDict allKeys] sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
Then iterate through those and add them to NSMutableArrays:
NSMutableArray *arrTVBuyCharge = [[NSMutableArray alloc] init];
NSMutableArray *arrTVBuyCost = [[NSMutableArray alloc] init];
for (NSString *key in sortedKeys) {
[arrTVBuyCharge addObject:key];
[arrTVBuyCost addObject:[tempDict objectForKey:key]];
}
For even better performance, use the initWithCapacity method for the NSMutableArrays since you know the size.
This is the standard way of doing it.
1) Get three objects separately :
NSArray *mainKeys = #[#"Freight", #"Fuel", #"Discount"];
NSArray *mainValues = #[[tempDict valueForKey:#"Freight"],
[tempDict valueForKey:#"Fuel"],
[tempDict valueForKey:#"Discount"]
];
[arrTVBuyCharge addObjectsFromArray:mainKeys];
[arrTVBuyCost addObjectsFromArray:mainValues];
2) Remove them from tempDict :
[tempDict removeObjectsForKeys:mainKeys];
3) Add the objects from Updated tempDict :
[arrTVBuyCharge addObjectsFromArray:(NSArray *)[tempDict allKeys]];
[arrTVBuyCost addObjectsFromArray:(NSArray *)[tempDict allValues]];
This will make Freight, Fuel and Discount to be at index 0, 1 and 2 in your new Arrays.
Man, NSMutableDictionary always returns keys in a disordered fashion, if you really want to maintain order then you can sort it in alphabetical order or you can add 01, 02 ,03 serial numbers before your values to sort them in the order they were put it, later trim the first two characters of the string and use it.

How to turn NSString to a number

I need to sort a list of files according to the number after "_" :
"filename_1" "filename_2" ......
I know that I can extract the number, then sort the filename with the number, but I have to consider what if some illegal name exist and the program turn to be long.
What I want to do is just simply compare the whole String, the same char must has the same number. But when I do [#"word" intValue], the result is zero if the String is not a number. I want to know is there a good way to turn a String into a number.
Take a look at NSString's method:
- (NSComparisonResult)compare:(NSString *)aString options:(NSStringCompareOptions)mask
and the NSNumericSearch option.
If you wish to sort them on your own then you will need to use the
- (NSComparisonResult)compare:(NSString *)aString;
routine.
Here is the reference to the NSComparisonResult capable outputs.
These constants are used to indicate how items in a request are ordered.
enum {
NSOrderedAscending = -1,
NSOrderedSame,
NSOrderedDescending
};
typedef NSInteger NSComparisonResult;
Constants:
NSOrderedAscending
The left operand is smaller than the right operand.
NSOrderedSame
The two operands are equal.
NSOrderedDescending
The left operand is greater than the right operand.
If you think it easier, your can fill an NSArray with your separated strings, then use something like the following:
sortedArray = [anArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
Link to a good QA from SO:
How to sort a NSArray alphabetically?
There is 1 final way I can think of in your case. That would be to use the hasPrefix method of NSString to make sure that each of your strings begins with "filename_" as a first validation. afterwards substring the overall string just getting the remaining string after the "filename_". If all of your filenames are to have a number of 1 or greater, then a 0 means the string is invalid at this point, else the intValue should return a valid positive integer, and you can sort via the integer values.
This should work:
NSString *good = #"filename_1";
NSString *bad = #"filename";
NSCharacterSet *letterSet= [NSCharacterSet letterCharacterSet];
good = [good stringyByTrimmingCharactersInSet:letterSet]; // 1
bad = [bad stringByTrimmingCharactersInSet:letterSet]; // <empty>
You can use following coe to sort the array containing the list of File Objects:
NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"fileName" ascending:YES];
[arrayOfFileNames sortUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]];
Hope this is helpful to you...
I think you can not compare it with NSString because NSString follows 1,10,11,12,13,14 .....2,20,21,22 ......this type of ascending order while integer follows like 0,1,2,3,4,5,6,7....... and so on..... So you have to split the last character from string then will have to compare.
well how to short string in ascending order ....
NSMutableArray *array = [NSMutableArray arrayWithObjects:#"f_1",#"f_2",#"f_12",#"f_6",#"f_9",#"f_4", nil];
NSSortDescriptor *name = [[[NSSortDescriptor alloc] initWithKey:#"" ascending:YES] init];
[array sortUsingDescriptors:[NSMutableArray arrayWithObjects:name, nil]];
but this will give you string shorting not according to number.
Thank You!

Comparing Strings in Objective-C

I'm writing a small app for the iphone and I'm trying to write a function that will insert an NSMutableString into an NSArray in alphabetical order. Also I'll be writing a sort to sort the entire array as well. For both cases I'm wondering what the best way of comparing NSMutableStrings is. Is there a specific function I can use?
Thanks for your help.
I think you're looking for
(NSComparisonResult)[aString compare: bString];
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/nsstring_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/compare:
You can use this or one of the related methods if you're doing insertion sort. However, if you want to do a one time sort of the NSMutableArray, you can use one of the NSMutableArray sorting methods such as sortUsingComparator:.
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html#//apple_ref/occ/instm/NSMutableArray/sortUsingComparator:
If you look under "Identifying and comparing strings" in the NSString reference, you'll find several options. They do slightly different things, since you might want to compare strings in different ways (e.g. are numbers compared in lexical or numeric order?). The most basic is compare: — you can probably start there and choose a more complicated version as needed.
I think this should work for you. This is my answer which I have taken from the link:
Comparing text in UITextView?
SOLUTION-1: I have modified it here a bit to make it more easier for your case:
Let us assume String1 is one NSString.
//Though this is a case sensitive comparison of string
BOOL boolVal = [String1 isEqualToString:#"My Default Text"];
//Here is how you can do case insensitive comparison of string:
NSComparisonResult boolVal = [String1 compare:#"My Default Text" options:NSCaseInsensitiveSearch];
if(boolVal == NSOrderedSame)
{
NSLog(#"Strings are same");
}
else
{
NSLog(#"Strings are Different");
}
Here if boolVal is NSOrderedSame then you can say that strings are same else they are different.
SOLUTION-2: Also you don't find this easy, you can refer to Macmade's answer under the same link.
Hope this helps you.
For sorting array
NSArray *sortedArray = [anArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
try BOOL ans = [str1 isEqualToString:str2];
Try NSArray's sortedArrayUsingSelector: method:
NSArray * stringArray = [NSArray arrayWithObjects:#"dddsss", #"aada", #"bbb", nil];
[stringArray sortedArrayUsingSelector:#selector(compare:)];
NSLog(#"%#", [stringArray sortedArrayUsingSelector:#selector(compare:)]);
Out put:
(
aada,
bbb,
dddsss
)
What's more, you can use NSSortDescriptor to decide ASC or DESC order.

Objective C: Create arrays from first array based on value

I have an array of strings that are comma separated such as:
Steve Jobs,12,CA
Fake Name,21,CA
Test Name,22,CA
Bill Gates,44,WA
Bill Nye,21,OR
I have those values in an NSScanner object so that I can loop through the values and get each comma seperated value using objectAtIndex.
So, what I would like to do, is group the array items into new arrays, based on a value, in this case, State. So, from those, I need to loop through, checking which state they are in, and push those into a new array, one array per state.
CA Array:
Steve Jobs,12,CA
Fake Name,21,CA
Test Name,22,CA
WA Array:
Bill Gates,44,WA
OR Array:
Bill Nye,21,OR
So in the end, I would have 3 new arrays, one for each state. Also, if there were additional states used in the first array, those should have new arrays created also.
Any help would be appreciated!
You can use a NSMutableDictionary of NSMutableArrays - if the state encountered isn't yet in the dictionary, add a new array.
NSMutableArray* arr = [states objectForKey:state];
if (arr == nil) {
arr = [NSMutableArray array];
[states setObject:arr forKey:state];
}
Then you can insert values into the array, preferably as objects though as Dave DeLong mentions.
You shouldn't be maintaining this data as CSV. That's asking for a world of hurt if you ever need to manipulate this data programmatically (such as what you're trying to do).
You can naïvely break this data up into an array using NSArray * portions = [line componentsSeparatedByString:#","];. Then create a custom object to store each portion (for an example, see this post), and then you can manipulate those objects almost effortlessly.
Naively: (assuming array of strings called strings)
NSMutableDictionary *states = [NSMutableDictionary dictionary];
for (NSString *string in strings) {
NSString *state = [[string componentsSeparatedByString:#", "] lastObject];
NSMutableArray *values = [states objectForKey:state];
if (values == nil) {
values = [NSMutableArray array];
[states setObject:value forKey:state];
}
[values addObject:string];
}
Number of things about this -- first of all, I'm not at my computer, so there is a high chance of typos and or things that I missed. Second, you probably want to adapt the components separated by string line to handle whitespace better.