NSNumber storing float. Please NO scientific notation? - ios

My code looks like this
NSNumber *inputToNumber = [NSNumber numberWithFloat:[textField.text floatValue]];
the value from the textfield is actually a telephone number. It's stored in NSNumber as an annoying (2.0)78966e+08
How can I just get NSNumber to store it as 0207896608?

I think that the basic idea to store a phone number into a NSNumber is flawed:
how do you discriminate between numbers with or without leading 0 ?
how do you store phone numbers from foreign countries ?
I would use NSString in place of NSNumber.

Just because it's called a number doesn't mean a "telephone number" is a number in the same sense that "5" or "pi" are.
Either you should treat a telephone number as a string, or you should create a TelephoneNumber model class to represent each one.

Consider that there are places in the world where numbers don't have leading 0's and where a number with a leading 0 is not the same as the same number without a leading 0.
05843924 != 5843924
So stop being lazy with that NSNumber hacks and build your own phone-number class.

Scientific notation is used in may computer languages as the default output of very large (or very small) numbers. If you want the number to be output as a decimal, you need to specify the output format (the implementation varies by language.)
Also, julesjacobs is correct. You should not use FLOAT for a phone number as it is subject to binary rounding errors. Using INT or STRING will save you lots of headaches.

If you need to be able to deal with it as numbers maybe you should break it up into its parts, and store each part as an integer.
01112223333
country code 0
area code 111
prefix 222
number 3333
Or you could store the whole thing as a string if you don't need to manipulate it.

Are you storing a phone number in a float? You should consider using an integer or string. Perhaps:
NSNumber *inputToNumber = [NSNumber numberWithInt:[textField.text intValue]];

Hey Guys what do you think of this, It seems to full-fill my purposes. Only UK at the moment so will worry about localization when I get a chance.
I use this to get to store the number
NSNumber *inputToNumber = [NSNumber numberWithLongLong:(long long)[[textField.text stringByReplacingOccurrencesOfString:#" " withString:#""] longLongValue]];
And this method formats my telephone number and takes care of the preceeding 0 mentioned.
-(NSString *)phoneNumberString:(NSNumber *)phoneNumber {
//Add a zero because NSNumber won't save a preceeding zero
NSString *telephoneString = [[NSString alloc] initWithFormat:#"0%#", [phoneNumber stringValue]];
if (telephoneString.length >= 4) {
NSString *firstPart = [[NSString alloc] initWithString: [telephoneString substringToIndex:4]];
NSString *secondPart = [[NSString alloc] initWithString: [telephoneString substringFromIndex:4]];
//Add the two parts together with a space inbetween
NSString *formattedTelephoneString = [NSString stringWithFormat:#"%# %#", firstPart, secondPart];
//send it back to the cellForRow TableCell Method
[firstPart release];
[secondPart release];
[telephoneString release];
return formattedTelephoneString;
}
else {
return telephoneString;
}
}
Thanks for all the comments. I'm gonna mark the answer as whoever suggested NSString as I fear I will revert to using NSString for this instead of my above workaround.

Related

Find difference between two comma separated NSMutableString

Suppose I have two NSMutableString like this:-
String 1 ----- {aaa,bss,cdd,dff,eee,fgh}
String 2 ----- {aaa,bss,cdd}
How can we find the the difference between String 1 & String 2 in an NSArray:-
Like this:- { dff,eee,fgh }
As mentioned in duplicate question it is different.
Put both these strings in two different NSMutableSets and then subtract 2nd from 1st.
You will have your result.
NSString* str1 = #"aaa,bss,cdd,dff,eee,fgh";
NSString* str2 = #"aaa,bss,cdd";
NSMutableSet *set1 = [NSMutableSet setWithArray:[str1 componentsSeparatedByString:#","]];
NSMutableSet *set2 = [NSMutableSet setWithArray:[str2 componentsSeparatedByString:#","]];
[set1 minusSet:set2];
NSLog(#"result %#",[set1 allObjects]);
Try with NSMutableArray to remove same objects.
For Eg.
NSString *s1 = #"aaa,bss,cdd,dff,eee,fgh";
NSString *s2 = #"aaa,bss,cdd";
NSArray *arr1 = [s1 componentsSeparatedByString:#","];
NSArray *arr2 = [s2 componentsSeparatedByString:#","];
NSMutableArray *resArray = [NSMutableArray arrayWithArray:arr1];
[resArray removeObjectsInArray:arr2];
NSString *res = [resArray componentsJoinedByString:#","];
NSLog(#"Result :: %#", res);
Hopefully, it'll help you.
Thanks.
First part of the problem is to separate each string into substrings separated by the commas.
To create the substrings you can use
[string substringFromIndex:index] - to get an NSString from that index foward
[string substringToIndex:index] - to get an NSString from the begining to that index
Or you could combine it into
[string substringWithRange:NSMakeRange(fisrtIndex, secondIndex)] - to get a strin from the first index to the second index
Those are the basic operations. But there are a lot more in this case you could use specifically:
[string componentsSeparatedByString:#","] to get an NSArray with all the substrings. That would have the problem of the '{' and '}' appearing in the first and last component. This can be solved in many ways:
by first trimming the string using the substring methods already explained
by using another method altogether
[string componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:#",{"]] The problem with this method is, because your strings start/end with one of the separators you would get the first/last component an empty string. You can just remove it from the array or ignore it or choose the other method, your choice.
Now that you know how to get the substrings all you need to know is how to compare the two. There are literally many ways to do this. I am just going to name a few. Of course each solution has its own advantages and disadvantages and code complexity.
1 - comparing each substring one by one the the other using isEqualToString:
2 - comparing each substring from one of the original strings with the full second original string by using [string2 rangeOfString:substring].location != NSNotFound
3 - if you have iOS 8 or OS X Yosemite you can use [string2 containsString:substring]
4 - You can transform the arrays of substrings into sets and then compare them as Ankit Srivastava suggested
5 - You can use the removeObjectsInArray to get the substrings that are not common between the two and then use that newly created array to removeObjectsInArray to the original and have just the common...
Really the possibilities are almost endless

get the last whitespace from nsstring in objective c

I have a large string set something like - Objective-C is the primary programming language you use when writing software for OS X and iOS. It’s a superset of the C programming language and provides object-oriented capabilities and a dynamic runtime. Objective-C inherits the syntax, primitive types, and flow control statements of C and adds syntax for defining classes and methods. It also adds language-level support for object graph management and object literals while providing dynamic typing and binding, deferring many responsibilities until runtime.
I wants to divide above string in the length of at least 15 characters strings which will be ending by whitespaces & store in an array. For this I have applied following logic which is working fine , But it will be busy the compiler in case of long strings like 1000000 characters , Please help me if you can suggest better way to meet by requirements .Thanks.
NSMutableArray *randomSelection = [[NSMutableArray alloc] init];
NSString *shortDescription = shortDesc_;
NSString *str=#"";
NSArray *iarray=[shortDescription componentsSeparatedByString:#" "];
NSInteger i=0;
while (i<iarray.count)
{
NSString *prevStr=str;
str=[prevStr stringByAppendingString:[[iarray objectAtIndex:i] stringByAppendingString:#" "]];
if(str.length>15)
{
[randomSelection addObject:prevStr];
str=[[iarray objectAtIndex:i] stringByAppendingString:#" "];
}
i++;
}
if(str.length>0)
[randomSelection addObject:str];
Let's consider your algorithm, which as you correctly state works.
You first break up your million characters into "words", so you have another million characters in memory at this point, and then you join the words into strings of 15 or more characters - and that will occupy another million or so characters of memory. Maybe you could remove the need for the intermediate million by breaking up the input directly at the right points? That should reduce your memory requirements by roughly 1/3 and save a fair bit of copying.
Next when building up your string of 15 or so characters you repeatedly call length to calculate the length of the newly extended string. However you know how long it is - the previous length + length of added word + 1 for the space. Maybe keeping track of the length would save worthwhile time?
But then you wouldn't need to keep track of the length at all if you broke the string in the right place, but is that possible?
Consider the methods:
rangeOfCharacterFromSet:options:range or rangeOfString:options:range; and
substringWithRange:
One of the first two can be used to easily find the range of characters which make up your next string of 15 or so, and the last enables you to extract it. No intermediate million or so characters in memory, no need to keep checking the length.
Will it be faster? Give it a go and find out!
HTH
Try this
int numberOfLetters = 15;
if ([text length]>numberOfLetters) {
NSMutableArray* strings = [[NSMutableArray alloc] init];
__block int checkedStringLenght = 0;
while (checkedStringLenght<text.length-1) {
int rest = (int)text.length - checkedStringLenght;
__block NSRange neededRange;
[text enumerateSubstringsInRange:NSMakeRange(checkedStringLenght, MIN(rest,numberOfLetters)) options:NSStringEnumerationByWords | NSStringEnumerationReverse usingBlock:^(NSString *substring, NSRange subrange, NSRange enclosingRange, BOOL *stop) {
unsigned long fin =subrange.location - checkedStringLenght-1;
if (fin == 0){
NSString* lastString = [text substringWithRange:NSMakeRange(checkedStringLenght, rest)];
if ([[strings lastObject] length] + rest <= numberOfLetters) {
[strings replaceObjectAtIndex:strings.count-1 withObject:[strings[strings.count-1] stringByAppendingString:lastString]];
} else [strings addObject:lastString];
checkedStringLenght+=rest;
}
else {
neededRange =NSMakeRange(checkedStringLenght, fin);
NSString *ch = [text substringWithRange:neededRange];
checkedStringLenght+=ch.length;
[strings addObject:ch];
}
*stop = YES;
}];
}
NSLog(#"%#",strings);
}
My while is executing only (int)(text.lenght/numberOfLetters)+1 times, your while - for each word. enumerateSubstringInRage:options: is executing 1 time for each while, because is getting the last word only.

Conversion issue from NSNumber to NSString

I'm parsing data from a JSON webservice and adding it to the database so when I insert an int, I have to convert it to NSNumber in this way it's working fine: 24521478
NSString *telephone = [NSString stringWithFormat:#"%#",[user objectForKey:#"telephone"]];
int telephoneInt = [telephone intValue];
NSNumber *telephoneNumber = [NSNumber numberWithInt:telephoneInt];
patient.telephone = telephoneNumber;
but when I want to display it and convert the NSNumber to NSString I'm getting wrong numbers: -30197
NSString *telephoneString = [NSString stringWithFormat:#"%d", [user.telephone intValue], nil];
labelTelephone.text =telephoneString ;
Can someone explain this?
NSNumber comes with dedicated methods for each data type.If you want to convert NSNumber to NSString use:
NSString *telephoneString = [user.telephone stringValue];
The issue may coming because of the data type you used for the variable patient.telephone
If you have control over the web service, then you should return the telephone number as string in the JSON
Reasons
if the telephone number begin with zero then the NSNumber will remove that zero as it has no value (ex: 00123456789 will be 123456789 which will wrong data)
You will not be able to display the telephone number is a user friendly way by adding "+" and "-" (ex: +123-456-789)
You really should make the json return the number as string if you have a control over that

How to truncate an NSString 'x' characters after a certain character is found

Say I have an NSString, it represents a price that otherwise would be a double of course. I am trying to make it truncate the string at the hundredths place so it is something like 19.99 instead of 19.99412092414 for example. Is there a way, once detecting the decimal like so...
if ([price rangeOfString:#"."].location != NSNotFound)
{
// Decimal point exists, truncate string at the hundredths.
}
for me to cut off the string 2 characters after that ".", without separating it into an array then doing a max size truncate on the decimal before finally reassembling them?
Thank you very much in advance! :)
This is string manipulation, not math, so the resulting value won't be rounded:
NSRange range = [price rangeOfString:#"."];
if (range.location != NSNotFound) {
NSInteger index = MIN(range.location+2, price.length-1);
NSString *truncated = [price substringToIndex:index];
}
This is mostly string manipulation, tricking NSString into doing that math for us:
NSString *roundedPrice = [NSString stringWithFormat:#"%.02f", [price floatValue]];
Or you might consider keeping all numeric values as numbers, thinking of strings as just a way to present them to the user. For that, use NSNumberFormatter:
NSNumber *priceObject = // keep these sorts values as objects
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle: NSNumberFormatterCurrencyStyle];
NSString *presentMeToUser = [numberFormatter stringFromNumber:priceObject];
// you could also keep price as a float, "boxing" it at the end with:
// [NSNumber numberWithFloat:price];

How to filter a string after a particular character in iOS? [duplicate]

This question already has answers here:
Split an NSString to access one particular piece
(7 answers)
Closed 9 years ago.
I want to filter string after character '='. For eg if 8+9=17 My output should be 17. I can filter character before '=' using NSScanner, how to do its reverse??? I need a efficient way to do this without using componentsSeparatedByString or creating an array
Everyone seems to like to use componentsSeparatedByString but it is quite inefficient when you just want one part of a string.
Try this:
NSString *str = #"8+9=17";
NSRange equalRange = [str rangeOfString:#"=" options:NSBackwardsSearch];
if (equalRange.location != NSNotFound) {
NSString *result = [str substringFromIndex:equalRange.location + equalRange.length];
NSLog(#"The result = %#", result);
} else {
NSLog(#"There is no = in the string");
}
Update:
Note - for this specific example, the difference in efficiencies is negligible if it is only being done once.
But in general, using componentsSeparatedByString: is going to scan the entire string looking for every occurrence of the delimiter. It then creates an array with all of the substrings. This is great when you need most of those substrings.
When you only need one part of a larger string, this is very wasteful. There is no need to scan the entire string. There is no need to create an array. There is no need to get all of the other substrings.
NSArray * array = [string componentsSeparatedByString:#"="];
if (array)
{
NSString * desiredString = (NSString *)[array lastObject]; //or whichever the index
}
else
{
NSLog(#""); //report error - = not found. Of array could somehow be not created.
}
NOTE:
Though this is very popular splitting solution, it is only worth trying whenever every substring separated by separator string is required. rmaddy's answer suggest better mechanism whenever the need is only to get small part of the string. Use that instead of this approach whenever only small part of the string is required.
Try to use this one
NSArray *arr = [string componentsSeparatedByString:#"="];
if (arr.count > 0)
{
NSString * firstString = [arr objectAtIndex:0];
NSString * secondString = [arr objectAtIndex:1];
NSLog(#"First String %#",firstString);
NSLog(#"Second String %#",secondString);
}
Output
First String 8+9
Second String 17
Use this:
NSString *a =#"4+6=10";
NSLog(#"%#",[a componentsSeparatedByString:#"="])
;
Log: Practice[7582:11303] (
"4+6",
10
)

Resources