can I convert + as an NSString to addition operator directly? - ios

I have a mathematical equation in string format.
Is there a way to convert #"+"(String constant) directly to addition operator in objective C
Or
I have to use If-Else statements to solve this equation ??

NSPredicate * parsed = [NSPredicate predicateWithFormat:#"123+456+678-985 = 0"];
NSExpression * left = [(NSComparisonPredicate *)parsed leftExpression];
NSNumber * result = [left expressionValueWithObject:nil context:nil];
float i = [result floatValue];

if([yourString isEqualToString:#"+"])
{
//Do something
}
This code should work.

You can use NSExpression to achieve this
NSString *expressionFormat = [NSString stringWithFormat:#"(%d %# %d)",firstNumber,arcthimaticOperator,secondNumber];
NSExpression *expression = [NSExpression expressionWithFormat:expressionFormat];
NSNumber *result = [expression expressionValueWithObject:nil context:nil];
NSLog(#"%#", result);
Please make sure you enter the correct format else the above code will throw exception.

Related

Use regular expression to find and replace the string from Textfield in NSString

I would like to use regular expression to find and replace the string. In my scenario {3} and {2} are UITextField tag values. Based on the tag value, I would like to replace the respective textfield values and calculate the string value using NSExpression.
Sample Input String :
NSString *cumputedValue = #"{3}*0.42/({2}/100)^2";
Note: The textFields are created dynamically based on JSON response.
I got the answer for this question. Here the computedString contains the value as "{3}*0.42/({2}/100)^2".
- (NSString *)autoCalculationField: (NSString *)computedString {
NSString *computedStringFormula = [NSString stringWithFormat:#"%#",computedString];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\{(\\d+)\\}"
options:0
error:nil];
NSArray *matches = [regex matchesInString:computedStringFormula
options:0
range:NSMakeRange(0, computedStringFormula.length)];
NSString *expressionStr = computedStringFormula;
for (NSTextCheckingResult *r in matches)
{
NSRange numberRange = [r rangeAtIndex:1];
NSString *newString = [NSString stringWithFormat:#"%.2f",[self getInputFieldValue:[computedStringFormula substringWithRange:numberRange]]];
expressionStr = [expressionStr stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"{%#}",[computedStringFormula substringWithRange:numberRange]] withString:newString];
}
NSExpression *expression = [NSExpression expressionWithFormat:expressionStr];
return [expression expressionValueWithObject:nil context:nil];
}
- (float)getInputFieldValue: (NSString *)tagValue {
UITextField *tempTextFd = (UITextField *)[self.view viewWithTag:[tagValue intValue]];
return [tempTextFd.text floatValue];
}
You could save the textField tags in a NSDictionary with the value that they represent.
After that use stringByReplacingOccurrencesOfString to replace the values that you wish to.
Something like this:
for (NSString *key in dict) {
cumputedValue = [cumputedValue stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"{#%}", key] withString:[NSString stringWithFormat:#"%#", dict objectForKey:#key]];
}
This way you can have the values replaced

Logical NSExpression evaluation [duplicate]

This question already has an answer here:
Calculate lessthan value using NSExpression?
(1 answer)
Closed 8 years ago.
This code works:
NSString* equation = #"2.5*3";
NSExpression* expresion = [NSExpression expressionWithFormat:equation, nil];
NSNumber* result = [expresion expressionValueWithObject:nil context:nil];
NSLog(#"%#", result); // 7.5
But this one doesn't, it ends up in a NSInvalidArgumentException
NSString* equation = #"2.5<=3";
NSExpression* expresion = [NSExpression expressionWithFormat:equation, nil];
NSNumber* result = [expresion expressionValueWithObject:nil context:nil];
NSLog(#"%#", result); //I wanted result to be 1, as the expression is true
Does anyone know if there's a way to use NSExpression to evaluate logical expressions like that one?
Thanks.
Use NSPredicate instead of NSExpression:
NSString* equation = #"2.5<=3";
NSPredicate* pre = [NSPredicate predicateWithFormat:equation];
BOOL result = [pre evaluateWithObject:nil];
NSLog(#"%#", (result ? #"YES" : #"NO"));

Regex in objective C

I want to extract only the names from the following string
bob!33#localhost #clement!17#localhost jack!03#localhost
and create an array [#"bob", #"clement", #"jack"].
I have tried NSString's componentsseparatedbystring: but it didn't work as expected. So I am planning to go for regEx.
How can I extract strings between ranges and add it to an array
using regEx in objective C?
The initial string might contain more than 500 names, would it be a
performance issue if I manipulate the string using regEx?
You can do it without regex as below (Assuming ! sign have uniform pattern in your all words),
NSString *names = #"bob!33#localhost #clement!17#localhost jack!03#localhost";
NSArray *namesarray = [names componentsSeparatedByString:#" "];
NSMutableArray *desiredArray = [[NSMutableArray alloc] initWithCapacity:0];
[namesarray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSRange rangeofsign = [(NSString*)obj rangeOfString:#"!"];
NSString *extractedName = [(NSString*)obj substringToIndex:rangeofsign.location];
[desiredArray addObject:extractedName];
}];
NSLog(#"%#",desiredArray);
output of above NSLog would be
(
bob,
"#clement",
jack
)
If you still want to get rid of # symbol in above string you can always replace special characters in any string, for that check this
If you need further help, you can always leave comment
NSMutableArray* nameArray = [[NSMutableArray alloc] init];
NSArray* youarArray = [yourString componentsSeparatedByString:#" "];
for(NSString * nString in youarArray) {
NSArray* splitObj = [nString componentsSeparatedByString:#"!"];
[nameArray addObject:[splitObj[0]]];
}
NSLog(#"%#", nameArray);
I saw the other solutions and it seemed no one tried to use real regular expressions here, so I created a solution which uses it, maybe you or someone else can use it as a possible idea in the future:
NSString *_names = #"bob!33#localhost #clement!17#localhost jack!03#localhost";
NSError *_error;
NSRegularExpression *_regExp = [NSRegularExpression regularExpressionWithPattern:#" ?#?(.*?)!\\d{2}#localhost" options:NSRegularExpressionCaseInsensitive error:&_error];
NSMutableArray *_namesOnly = [NSMutableArray array];
if (!_error) {
NSLock *_lock = [[NSLock alloc] init];
[_regExp enumerateMatchesInString:_names options:NSMatchingReportProgress range:NSMakeRange(0, _names.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
if (result.numberOfRanges > 1) {
if ([_lock tryLock]) [_namesOnly addObject:[_names substringWithRange:[result rangeAtIndex:1]]], [_lock unlock];
}
}];
} else {
NSLog(#"error : %#", _error);
}
the result can be logged...
NSLog(#"_namesOnly : %#", _namesOnly);
...and that will be:
_namesOnly : (
bob,
clement,
jack
)
Or even something as simple as this will do the trick:
NSString *strNames = #"bob!33#localhost #clement!17#localhost jack!03#localhost";
strNames = [[strNames componentsSeparatedByCharactersInSet:[[NSCharacterSet letterCharacterSet] invertedSet]]
componentsJoinedByString:#""];
NSArray *arrNames = [strNames componentsSeparatedByString:#"localhost"];
NSLog(#"%#", arrNames);
Output:
(
bob,
clement,
jack,
""
)
NOTE: Ignore the last element index while iterating or whatever
Assumption:
"localhost" always comes between names
I know it ain't so optimized but it's one way to do this

How to do primary maths with cocoa and cocoa touch

I'm quite new to xcode and am making a app where you put two numbers in to a text input and I don't know how to make xcode to do the adding sum, I tried this but it did not work
self.answer.text = self.label.text + self.label2.text
Does anybody know how to do this.
Use :
NSInteger firstNumber=[self.label.text integerValue];
NSInteger secondNumber=[self.label2.text integerValue];
NSInteger total=firstNumber + secondNumber;
NSString *string=[NSString stringWithFormat:#"%d",total];
self.answer.text = string;
If you want to take double value replace integerValue with doubleValue
Here is another interesting way:
//Some string with expression which was taken from self.label.text
NSString *s = #"2*(2.15-1)-4.1";
NSExpression *expression = [NSExpression expressionWithFormat:s];
float result = [[expression expressionValueWithObject:nil context:nil] floatValue];
NSLog(#"%f", result);
self.answer.text=[NSString stringWithFormat:#"%f",result];

ios get rid of decimal place if number is an int

I have an app that imports a long list of data of a csv.
I need to work with the numbers fetched, but in order to do this, I need to get rid of the decimal place on numbers that are ints, and leave untoched numbers that have x.5 as decimal
for example
1.0 make it 1
1.50 make it 1.5
what would be the best way to accomplish this?
thanks a lot!
You can use modf to check if the fraction part equates to zero or not.
-(BOOL)isWholeNumber:(double)number
{
double integral;
double fractional = modf(number, &integral);
return fractional == 0.00 ? YES : NO;
}
Will work for some boundary cases as well.
float a = 15.001;
float b = 16.0;
float c = -17.999999;
NSLog(#"a %#", [self isWholeNumber:a] ? #"YES" : #"NO");
NSLog(#"b %#", [self isWholeNumber:b] ? #"YES" : #"NO");
NSLog(#"c %#", [self isWholeNumber:c] ? #"YES" : #"NO");
Output
a NO
b YES
c NO
Other solutions do not work if the number is very close to a whole number. I am not sure if you have this requirement.
After that you can display them as you like using the NSNumberFormatter, one for whole numbers and one for fractions.
A simple NSNumberFormatter should achieve this for you:
float someFloat = 1.5;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setAllowsFloats:YES];
[formatter setMaximumFractionDigits:1];
NSString *string = [formatter stringFromNumber:[NSNumber numberWithFloat:someFloat]];
Of course this assumes that you only have decimals in the tenths that you want to keep, for example if you used "1.52" this would return "1.5" but judging by your last post on rounding numbers to ".5" this shouldn't be a problem.
This code achieves what you want
float value1 = 1.0f;
float value2 = 1.5f;
NSString* formattedValue1 = (int)value1 == (float)value1 ? [NSString stringWithFormat:#"%d", (int)value1] : [NSString stringWithFormat:#"%1.1f", value1];
NSString* formattedValue2 = (int)value2 == (float)value2 ? [NSString stringWithFormat:#"%d", (int)value2] : [NSString stringWithFormat:#"%1.1f", value2];
This kind of thing could be done in a category so how about
// untested
#imterface NSString (myFormats)
+(NSString)formattedFloatForValue:(float)floatValue;
#end
#implementation NSString (myFormats)
+(NSString)formattedFloatForValue:(float)floatValue
{
return (int)floatValue == (float)floatValue ? [NSString stringWithFormat:#"%d", (int)floatValue] : [NSString stringWithFormat:#"%1.1f", floatValue];
}
#end
// usage
NSLog(#"%#", [NSString formattedFloatForValue:1.0f]);
NSLog(#"%#", [NSString formattedFloatForValue:1.5f]);

Resources