How to implement number comparison like in the native iPhone contacts app? - ios

I want to compare two numbers, like in case, for e.g. the number is 987654.
It can be saved as +91 987654 or 0987654. But while searching or comparing, the number exactly matches and shows properly.
Right now I am using this code to compare the exact number. How do I enhance it?
// Remove non numeric characters from the phone number
phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] componentsJoinedByString:#""];
NSPredicate *predicate = [NSPredicate predicateWithBlock: ^(id record, NSDictionary *bindings) {
ABMultiValueRef phoneNumbers = ABRecordCopyValue( (__bridge ABRecordRef)record, kABPersonPhoneProperty);
BOOL result = NO;
for (CFIndex i = 0; i < ABMultiValueGetCount(phoneNumbers); i++) {
NSString *contactPhoneNumber = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
contactPhoneNumber = [[contactPhoneNumber componentsSeparatedByCharactersInSet: [[NSCharacterSet alphanumericCharacterSet] invertedSet]] componentsJoinedByString:#""];
//Comparing the string are equal. phoneNumber is the number I am comparing to.
if ([contactPhoneNumber isEqualToString:phoneNumber]) {
result = YES;
break;
}
}
CFRelease(phoneNumbers);
return result;
}];
The above code results YES, only if the contactPhoneNumber and phoneNumber are exactly same.
Not when 0987654 or +91 987654 with 987654.
The same thing works in WhatsApp number comparison too.
Can anyone give any leads?

Alright, I know that this isn't the neatest code, but...
NSString *originalPhoneNumber = [insert phone String];
int phoneNumber = [originalPhoneNumber intValue];
NSString *phoneFormatOne;//This will be your number formatted like 0987654
NSString *phoneFormatTwo;//This will be your number formatted like +91 987654
int phoneNumberFormatOne = [phoneFormatOne intValue];
NSString *partOne = [phoneFormatTwo substringWithRange:NSMakeRange(1,3)];
NSString *partTwo = [phoneFormatTwo substringWithRange:NSMakeRange(4,10)];
int phoneNumberFormatTwo = [partOne intValue]*1000000 + [partTwo intValue];
Now you have all three in integer format, called phoneNumber, phoneNumberFormatOne, and phoneNumberFormatTwo. You can now just compare integers with an == in a if statement.

Related

How to remove white space from Phone Number in iOS [duplicate]

This question already has answers here:
How to remove non numeric characters from phone number in objective-c?
(5 answers)
Closed 6 years ago.
I can't remove white space from Phone Number in iOS app.
Here is my codes.
ABMultiValueRef multiPhones = ABRecordCopyValue(person, kABPersonPhoneProperty);
for (CFIndex iPhone = 0; iPhone < ABMultiValueGetCount(multiPhones); iPhone++)
{
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(multiPhones, iPhone);
NSString *phoneNumber = (__bridge NSString *) phoneNumberRef;
if (phoneNumber == nil) {
phoneNumber = #"";
}
if (phoneNumber.length == 0) continue;
// phone number = (217) 934-3234
phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:#"(" withString:#""];
phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:#")" withString:#""];
phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:#"-" withString:#""];
phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:#" " withString:#""];
// phone number = 217 9343234
[phoneNumbers addObject:phoneNumber];
}
I expect to get without white space. But it is not removed from the phone number.
How can I fix? Please help me. Thanks
You can do something a lot simpler than what you're currently doing with NSCharacterSet. Here's how:
NSCharacterSet defines a collection of characters. There are a few standard ones, such as decimalDigitsCharacterSet and alphaNumericCharacterSet.
There's also a neat method called invertedSet which returns a character set with all of the characters not included in the current one. Now, we need just one more bit of information.
NSString has a method called componentsSeparatedByCharactersInSet:, which gives you back an NSArray of the parts of the string, broken up around the characters in the characterSet you supply.
NSArray has a complementary function, componentsJoinedWithString: which you can use to turn the elements of an array (back) into a string. See where this is going?
First, define a character set that we want to include in our final output:
NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];
Now, get everything else.
NSCharacterSet *illegalCharacters = [digits invertedSet]
Once we have the character set that we want, we can break out the string and reconstruct it:
NSArray *components = [phoneNumber componentsSeperatedByCharactersInSet:illegalCharacters];
NSString *output = [components componentsJoinedByString:#""];
That should give you the correct output. Four lines, and you're done:
NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];
NSCharacterSet *illegalCharacters = [digits invertedSet];
NSArray *components = [phoneNumber componentsSeparatedByCharactersInSet:illegalCharacters];
NSString *output = [components componentsJoinedByString:#""];
You can use the whitespaceCharacterSet do do something similar to trim whitespace off of strings.
NSHipster has a great article about this, too.
EDIT:
If you want to include other symbols, such as the + prefix or parenthesis, you can create custom character sets with characterSetWithCharactersInString:. If you have two character sets, such as the decimal digits and the custom one you created, you could use NSMutableCharacterSet to modify the character set you have to include other characters.

how to get single characters from string in ios for Gujrati language(other language)

I am trying to get single characters from NSString, like "ઐતિહાસિક","પ્રકાશન","ક્રોધ". I want output like 1)ઐ,તિ,હા,સિ,ક 2) પ્ર,કા,શ,ન 3) ક્રો,ધ, but output is coming like this 1)ઐ , ત , િ , હ , િ , ક 2) પ , ્ , ર , ક , ા , શ , ન 3)ક , ્ , ર , ો , ધ
I have used code like below:
NSMutableArray *array = [[NSMutableArray alloc]init];
for (int i=0; i<strElement.length; i++)
{
NSString *str = [strElement substringWithRange:NSMakeRange(i, 1)];
[array addObject:str];
}
NSLog(#"%#",array);
Let's take strElement as "ક્રોધ" then I got output like this ક , ્ , ર , ો , ધ
But I need output like this ક્રો,ધ
Is there any way that I can get the desired output? Any method available directly in iOS or need to create it by my self then any way or idea how to create it?
Any help is appreciated
Your code is assuming that each character in the string is a single unichar value. But it is not. Some of the Unicode characters are composed of multiple unichar values.
The solution is to use rangeOfComposedCharacterSequenceAtIndex: instead of substringWithRange: with a fixed range length of 1.
NSString *strElement = #"ઐતિહાસિક પ્રકાશન ક્રોધ";
NSMutableArray *array = [[NSMutableArray alloc]init];
NSInteger i = 0;
while (i < strElement.length) {
NSRange range = [strElement rangeOfComposedCharacterSequenceAtIndex:i];
NSString *str = [strElement substringWithRange:range];
[array addObject:str];
i = range.location + range.length;
}
// Log the results. Build the results into a mutable string to avoid
// the ugly Unicode escapes shown by simply logging the array.
NSMutableString *res = [NSMutableString string];
for (NSString *str in array) {
if (res.length) {
[res appendString:#", "];
}
[res appendString:str];
}
NSLog(#"Results: %#", res);
This outputs:
Results: ઐ, તિ, હા, સિ, ક, , પ્ર, કા, શ, ન, , ક્રો, ધ

How do I count the occurrences of ALL characters of a string?

I am trying to find the number of times each character in a string is used. for example, in the string "wow" I would like to count the number of times the character "w" is used and the number of times the character "o" is used. I would then like to add these characters to an NSMutableArray. Is there a programmatic way to count the number of times all specific characters are used? To get the number of occurrences of ALL characters in an NSString? Or would I have to go through the process of counting the occurrences of each individual character separately?
See iOS - Most efficient way to find word occurrence count in a string
NSString *string = #"wow";
NSCountedSet *countedSet = [NSCountedSet new];
[string enumerateSubstringsInRange:NSMakeRange(0, [string length])
options:NSStringEnumerationByComposedCharacterSequences | NSStringEnumerationLocalized
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){
// This block is called once for each word in the string.
[countedSet addObject:substring];
// If you want to ignore case, so that "this" and "This"
// are counted the same, use this line instead to convert
// each word to lowercase first:
// [countedSet addObject:[substring lowercaseString]];
}];
NSLog(#"%#", countedSet);
NSLog(#"%#", [countedSet allObjects]);
NSLog(#"%d", [countedSet countForObject:#"w"]);
The exact answer depends on some questions -
Do you only want to count the characters a-z or do you want punctuation as well?
Do you need to count unicode characters or just 8 bit characters?
Is case important ie. is A different to a?
Assuming you only want to count 8 bit, a-z independent of case, you could use something like -
- (NSArray *)countCharactersInString:(NSString *)inputString
{
NSMutableArray *result=[[NSMutableArray alloc]initWithCapacity:26];
for (int i=0;i<26;i++) {
[result addObject:[NSNumber numberWithInt:0]];
}
for (int i=0;i<[inputString length];i++)
{
unichar c=[inputString characterAtIndex:i];
c=tolower(c);
if (isalpha(c))
{
int index=c-'a';
NSNumber *count=[result objectAtIndex:index];
[result setObject:[NSNumber numberWithInt:[count intValue]+1] atIndexedSubscript:index];
}
}
return (result);
}
An alternative approach is to use an NSCountedSet - it handles all characterspunctuation etc, but will be 'sparse' - there is no entry for a character that is not present in the string. Also, the implementation below is case sensitive - W is different to w.
- (NSCountedSet *)countCharactersInString:(NSString *)inputString
{
NSCountedSet *result=[[NSCountedSet alloc]init];
for (int i=0;i<[inputString length];i++)
{
NSString *c=[inputString substringWithRange:NSMakeRange(i,1)];
[result addObject:c];
}
return result;
}
NSString *str = #"Program to Find the Frequency of Characters in a String";
NSMutableDictionary *frequencies = [[NSMutableDictionary alloc]initWithCapacity:52];
initWithCapacity:52 - capacity can be more depends on character set (for now : a-z, A-Z)
for (short i=0; i< [str length]; i++){
short index = [str characterAtIndex:i];
NSString *key = [NSString stringWithFormat:#"%d",index];
NSNumber *value = #1;
short frequencyCount=0;
if ([frequencies count] > 0 && [frequencies valueForKey:key]){
frequencyCount = [[frequencies valueForKey:key] shortValue];
frequencyCount++;
value = [NSNumber numberWithShort:frequencyCount];
[frequencies setValue:value forKey:key];
}
else{
[frequencies setValue:value forKey:key];
}
}
To display occurrence of each character in string
[frequencies enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSString *ky = (NSString*)key;
NSNumber *value = (NSNumber*)obj;
NSLog(#"%c\t%d", ([ky intValue]), [value shortValue]);
}];

stringByReplacingOccurrencesOfString only works on some objects (NSString black in debugger instead of blue)

I have a method for getting all the contacts from the iPhone contacts app and i want to add the phone numbers to an object after i have removed all the spaces in the phone number string. The problem is that this only works for some of the contacts. I have noticed that in the debugger the string-objects sometimes show in a blue color and sometimes in black. Anybody have a clue what is going on here?
Images:
Does not remove spaces in phone number
http://ctrlv.in/293692
Removes spaces in phone number
http://ctrlv.in/293691
Code:
ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
CFArrayRef sortedPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);
//RETRIEVING THE FIRST NAME AND PHONE NUMBER FROM THE ADDRESS BOOK
CFIndex number = CFArrayGetCount(sortedPeople);
NSString *firstName;
NSString *phoneNumberFromContact;
for(int i = 0; i < number; i++)
{
ABRecordRef person = CFArrayGetValueAtIndex(sortedPeople, i);
firstName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
phoneNumberFromContact = (__bridge NSString *) ABMultiValueCopyValueAtIndex(phones, 0);
if(phoneNumberFromContact != NULL)
{
Contact *contact = [[Contact alloc]init];
contact.firstName = firstName;
phoneNumberFromContact = [phoneNumberFromContact stringByReplacingOccurrencesOfString:#" " withString:#""];
contact.phoneNumber = phoneNumberFromContact;
[self.contacts addObject:contact];
}
}
There are many characters that appear as spaces in NSStrings. Removing all instances of all of them is rather difficult. The best method for your case is to keep only the characters you want (numbers). As the answer you referenced states you need to create a set of characters to keep:
NSCharacterSet *numbers = [NSCharacterSet
characterSetWithCharactersInString:#"0123456789"];
Then you need to remove everything but those characters. This can be done in a few different ways. The scanner in the answer you suggested is likely the fastest. But the way with the fewest lines of code (and in my mind most readable) would be something like:
number = [[number componentsSeparatedByCharactersInSet: numbers] componentsJoinedByString: #""];
It may be slow, so if you do this a million times then keep to the scanner.

Parse all integers from string in Objective-C

I have a problem how to get all integer values from string in Objective-C
NSString *numbers = #"1, 2";
int number = [numbers intValue];
But this just takes the first number (1) but I need both of them.
Thank you guys.
Try something like this:
NSArray *listOfNumbers = [numbers componentsSeparatedByString:#","];
for (NSString *numberAsString in listOfNumbers) {
int number = [numberAsString intValue]; // you might want to trim the string first
}
This is for if they're always separated by a ", ":
NSString *numbers = #"1, 2";
NSArray *numberTokens = [numbers componentsSeparatedByString:#", "];
for (NSString *token in numberTokens) {
NSLog(#"%i", token.integerValue);
}
This solution allows you to specify multiple characters that might separate the numbers:
NSString *numbers = #"1, 2";
NSArray *numberTokens = [numbers componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#", "]];
for (NSString *token in numberTokens) {
if (token.length > 0) {
NSLog(#"%#: %i", token, token.integerValue);
}
}

Resources