I wonder if someone can help me get total route distance in Heremap iOS sdk. According to the document, the following should do it, but I only ever get back values that borders on infinity, and that' just evil. Can someone please provide a working example? I am running this in the simulator but that shouldn't really matter.
unsigned long long distance_ul = [NMANavigationManager sharedNavigationManager].distanceToDestination;
NMAUint64 distance_i64 = [NMANavigationManager sharedNavigationManager].distanceToDestination;
Your second usage NMAUint64 distance = [NMANavigationManager sharedNavigationManager].distanceToDestination; is ok. Then you should calculate your distance by yourself. Below is an example for the metric system
- (NSString *)distanceToMetricStringFromLongValue:(NMAUint64)value {
NSString *distanceText = #"";
if (value < 250) {
NMAUint64 distance = (NMAUint64)round(value / 5.0) * 5;
if (showZeroDistance || distance > 0) {
distanceText = [NSString stringWithFormat:#"%lld m", distance];
}
} else if (value < 500) {
NMAUint64 distance = (NMAUint64)round(value / 10.0) * 10;
if (showZeroDistance || distance > 0) {
distanceText = [NSString stringWithFormat:#"%lld m", distance];
}
} else if (value < 1000) {
NMAUint64 distance = (NMAUint64)round(value / 50.0) * 50;
distanceText = [NSString stringWithFormat:#"%lld m", distance];
} else {
double distance = value / 1000.0;
if (distance >= 10.0) {
distanceText = [NSString stringWithFormat:#"%0.0f km", round(distance)];
} else {
distanceText = [NSString stringWithFormat:#"%0.1f km", distance];
}
}
}
When you create route on map with below method
- (nullable NSProgress *)calculateRouteWithStops:(nonnull NSArray *)stops
routingMode:(nonnull NMARoutingMode *)mode
completionBlock:(nullable NMACalculateResultBlock)completion
Find route length from NMARoute object
NMARoute* route = routeResult.routes[m];
NSLog(#"Route Length is :----- %lu",(unsigned long)route.length);
Official document link
I'm building my own alternative to the Levenshtein distance to train myself in objective-c. This class will get a few sentences, only 2 during initial testing and return how many percent correct the sentence is. How many percent matches with the "correct sentence".
Basically what it does is it gets 2 sentences, (only 2 words during initial testing really) and calculates. But I get some strange NSLog's.
If I enter 1989 and 199 it'll return 75% correct - which is the correct answer. However, if I enter "orange" and "oange" - it returns 50% correct when correct is 83% (right??)
This is the code calling the method:
-(void)compare {
// Take each and every sentence from the users source and check it against the other sources. If it contains 2 or more words/numbers that are equal, i'll get "investigated" further
NSMutableArray *userSentences = [[MyManager sharedManager] contentSentencesList];
NSMutableArray *serverSentences = [NSMutableArray arrayWithArray:getSentencesFromText(serverText)];
// Sample sentences
[userSentences insertObject:#"oange" atIndex:userSentences.count];
[serverSentences insertObject:#"orange" atIndex:serverSentences.count];
// For-statement integers
int i = 0;
int b = 0;
for (i = 0; i < userSentences.count; i++) {
// Check first sentence
NSString *userSentence;
NSString *serverSentence;
// Check similarity of the two sentences, get percent and add to centerPercent
for (b = 0; b < serverSentences.count; b++) {
// Compare sentences
userSentence = userSentences[i];
serverSentence = serverSentences[b];
// Compare sentences with custom class
// Initialize Distance class
SourcerDistance *wordDistance = [[SourcerDistance alloc] init];
// Create resultPercent integer and calculate it
int resultPercent = [wordDistance distanceBetween:userSentence serverSentence:serverSentence];
NSLog(#"%#%d", #"FinishViewController result: ", resultPercent);
// Add resultPercent to averagePrecent and increase averagPercentToDivide by 1
centerPercent = centerPercent + resultPercent;
centerPercentToDivide++;
}
// Set and display resultoppositeSpelling
// averagePercent = centerPercent / centerPercentToDivide;
// Use an integer to remove decimals
[self presentResult];
}
}
and this is the other class:
#import "SourcerDistance.h"
#implementation SourcerDistance
-(int)distanceBetween:(NSString *)userSentence serverSentence:(NSString *)serverSentence {
// Declare the 2 arrays containing all the words from the user's source and the developer's source
NSArray *developerSourceSentence = [self getWords:serverSentence];
NSArray *userSourceSentence = [self getWords:userSentence];
// Declare variables that'll be use for for-statements
int developerWordsLoop = developerSourceSentence.count;
int userWordsLoop = userSourceSentence.count;
// Declare variables required for matching (average of all words)
float centerPercent = 0; // This is for ALL words in total
float centerPercentToDivide = 0; // This is for all words in total
// Single-word variables
float totalCharacters = 0;
float matchingCharacters = 0;
float percentMatchingSingleWord = 0;
NSLog(#"%#%d", #"userSourceSentenceCount: ", userSourceSentence.count);
NSLog(#"%#%d", #"developerSourceSentenceCount: ", developerSourceSentence.count);
// Loop through all of the user words
for (userWordsLoop = 0; userWordsLoop < userSourceSentence.count; userWordsLoop++) {
// Loop through all of the developer words
for (developerWordsLoop = 0; developerWordsLoop < developerSourceSentence.count; developerWordsLoop++) {
// Declare variables that contain all the characters of the user- and developer-words
NSMutableArray *userCharacters = [self getCharacters:userSourceSentence[userWordsLoop]];
NSMutableArray *developerCharacters = [self getCharacters:developerSourceSentence[developerWordsLoop]];
// Compare characters
matchingCharacters = [self compareCharacters:userCharacters developerCharacters:developerCharacters];
// Set the variables
totalCharacters = developerCharacters.count;
percentMatchingSingleWord = matchingCharacters / totalCharacters * 100;
NSLog(#"%#%f", #"totalCharacters", totalCharacters);
NSLog(#"%#%f", #"matchingCharacters", matchingCharacters);
NSLog(#"%#%f", #"iterate", percentMatchingSingleWord);
centerPercent = centerPercent + percentMatchingSingleWord;
centerPercentToDivide++;
}
}
// Declare variables used with final result
float finalPercentFloat = 0;
int finalPercent = 0;
NSLog(#"%#%f", #"centerPercent: ", centerPercent);
NSLog(#"%#%f", #"centerPercentToDivide: ", centerPercentToDivide);
finalPercentFloat = centerPercent/centerPercentToDivide;
NSLog(#"%#%f", #"finalPercent: ", finalPercentFloat);
finalPercent = (int)finalPercentFloat;
return finalPercent;
}
-(float)compareCharacters:(NSMutableArray *)userCharacters developerCharacters:(NSMutableArray *)developerCharacters {
// Declare result variables and other required variables
float matchingCharacters;
int userCharactersLoop = 0;
int developerCharactersLoop = 0;
// Loop through all of the userCharacters
for (userCharactersLoop = 0; userCharactersLoop < userCharacters.count; userCharactersLoop++) {
// Loop through all of the developerCharacters
for (developerCharactersLoop = 0; developerCharactersLoop < developerCharacters.count; developerCharactersLoop++) {
// Match every character here
if ([userCharacters[userCharactersLoop] isEqualToString:developerCharacters[developerCharactersLoop]]) {
// Increase matchingCharacters
matchingCharacters++;
} else {
// Do nothing
}
}
}
// Return result variable
return matchingCharacters;
}
-(NSArray *)getWords:(NSString *)sentence {
// Get words of sentence from developer-source
NSArray *sentenceWords;
NSString *serverSentenceToRead = sentence;
sentenceWords = [serverSentenceToRead componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#":;.!? "]
];
// Return developer words
return sentenceWords;
}
-(NSMutableArray *)getCharacters:(NSString *)word {
NSMutableArray *wordCharacters = [[NSMutableArray alloc] initWithCapacity:[word length]];
for (int i=0; i < [word length]; i++) {
NSString *ichar = [NSString stringWithFormat:#"%c", [word characterAtIndex:i]];
[wordCharacters addObject:ichar];
}
// Return the characters of the word
return wordCharacters;
}
#end
NSLog:
2014-09-03 20:22:32.015 Sourcer[27532:60b] userSourceSentenceCount: 1
2014-09-03 20:22:32.017 Sourcer[27532:60b] developerSourceSentenceCount: 1
2014-09-03 20:22:32.018 Sourcer[27532:60b] totalCharacters6.000000
2014-09-03 20:22:32.018 Sourcer[27532:60b] matchingCharacters3.001519
2014-09-03 20:22:32.019 Sourcer[27532:60b] iterate50.025322
2014-09-03 20:22:32.020 Sourcer[27532:60b] centerPercent: 50.025322
2014-09-03 20:22:32.021 Sourcer[27532:60b] centerPercentToDivide: 1.000000
2014-09-03 20:22:32.021 Sourcer[27532:60b] finalPercent: 50.025322
2014-09-03 20:22:32.022 Sourcer[27532:60b] FinishViewController result: 50
2014-09-03 20:22:32.022 Sourcer[27532:60b] averagePercent (float): 50.000000
What am I doing wrong here? Is it possible for anyone to understand the code and help me find out what's wrong? There's something odd about this algorithm
Thanks a lot!
(I know I'm kinda reinventing the wheel, but I want to try :))
Sincerely,
Erik
I have the following code:
NSDate *myDate = [datePickerControl date];
NSDateFormatter *format = [[NSDateFormatter alloc]init];
[format setDateFormat:#"dd-MM"];
NSString *getDate = [format stringFromDate:myDate];
NSArray *array = [NSArray arrayWithObjects:#"15-06",#"15-07",#"15-08",nil];
for (int i = 0; i < ([array count]); i++) {
NSLog(#"i = %i", i);
NSString *stringToCheck = (NSString *)[array objectAtIndex:i];
if ([getDate isEqualToString:stringToCheck]) {
[signWow setText:[NSString stringWithFormat:#"Your sign is Scorpion"]];
}}
It uses Date Picker to determine date of birth and then to compare the date with a date from NSArray. But it's too difficult to type in all the dates related to specific Zodiac sign.
So, is it possible to make an array which contains all dates between for example 02/12 (dd/MM) and 03/15?
Take a look at screenshot here.
Please, give some code, because I'm new to Objective-C... :)
How about using tuple... (Swift)
func getZodiacSign(_ date:Date) -> String{
let calendar = Calendar.current
let d = calendar.component(.day, from: date)
let m = calendar.component(.month, from: date)
switch (d,m) {
case (21...31,1),(1...19,2):
return "aquarius"
case (20...29,2),(1...20,3):
return "pisces"
case (21...31,3),(1...20,4):
return "aries"
case (21...30,4),(1...21,5):
return "taurus"
case (22...31,5),(1...21,6):
return "gemini"
case (22...30,6),(1...22,7):
return "cancer"
case (23...31,7),(1...22,8):
return "leo"
case (23...31,8),(1...23,9):
return "virgo"
case (24...30,9),(1...23,10):
return "libra"
case (24...31,10),(1...22,11):
return "scorpio"
case (23...30,11),(1...21,12):
return "sagittarius"
default:
return "capricorn"
}
}
You should not need to enter every date for each sign. Instead, enter a table of the starting and ending month and day for each sign.
You would then take the user's selected date, use a Gregorian NSCalendar to extract the month and day units from the date, and then compare the user-entered date to the ranges for each sign.
BTW, it's "Scorpio", not "Scorpion".
Here's the most straightforward way to do it. Yes it's long, and yes it's not the most efficient, but it is definitely the easiest to understand, and it's already written for you. Cheers :)
P.S. This is going off of the Tropical zodiac (the standard, as opposed to the Sidereal zodiac based off of the Hindu system), and in response to Zev, Ophiuchus only affected each sign's corresponding constellation, but the sign's and their dates remained unaffected.
Here's the code:
-(void)getZodiacFromBirthday {
NSString *UserBirthday = #"09/09/99";
NSArray *birthArray = [UserBirthday componentsSeparatedByString:#"/"];
NSString *month = birthArray[0];
NSString *day = birthArray[1];
if ([month isEqualToString:#"01"]) {
if ([day intValue] >= 21) {
sign = #"Aquarius";
} else {
sign = #"Capricorn";
}
} else if ([month isEqualToString:#"02"]) {
if ([day intValue] >= 20) {
sign = #"Pisces";
} else {
sign = #"Aquarius";
}
} else if ([month isEqualToString:#"03"]) {
if ([day intValue] >= 21) {
sign = #"Aries";
} else {
sign = #"Pisces";
}
} else if ([month isEqualToString:#"04"]) {
if ([day intValue] >= 21) {
sign = #"Taurus";
} else {
sign = #"Aries";
}
} else if ([month isEqualToString:#"05"]) {
if ([day intValue] >= 22) {
sign = #"Gemini";
} else {
sign = #"Taurus";
}
} else if ([month isEqualToString:#"06"]) {
if ([day intValue] >= 22) {
sign = #"Cancer";
} else {
sign = #"Gemini";
}
} else if ([month isEqualToString:#"07"]) {
if ([day intValue] >= 23) {
sign = #"Leo";
} else {
sign = #"Cancer";
}
} else if ([month isEqualToString:#"08"]) {
if ([day intValue] >= 23) {
sign = #"Virgo";
} else {
sign = #"Leo";
}
} else if ([month isEqualToString:#"09"]) {
if ([day intValue] >= 24) {
sign = #"Libra";
} else {
sign = #"Virgo";
}
} else if ([month isEqualToString:#"10"]) {
if ([day intValue] >= 24) {
sign = #"Scorpio";
} else {
sign = #"Libra";
}
} else if ([month isEqualToString:#"11"]) {
if ([day intValue] >= 23) {
sign = #"Sagittarius";
} else {
sign = #"Scorpio";
}
} else if ([month isEqualToString:#"12"]) {
if ([day intValue] >= 22) {
sign = #"Capricorn";
} else {
sign = #"Sagittarius";
}
}
NSLog(#"Sign: %#", sign);
}
For those using swift, i must thanks Duncan C. his solution helped me a lot:
in case that date is "dd/MM/yyyy"
func getZodiacalSign(date:String) -> String {
let f = date.components(separatedBy: "/")
let day = Int(f[0])
let month = Int(f[1])
switch month {
case 1: return (day! >= 21) ? "Aquarius" : "Capricorn";
case 2: return (day! >= 20) ? "Picis" : "Aquarius";
case 3: return (day! >= 21) ? "Aries" : "Pisces";
case 4: return (day! >= 21) ? "Taurus" : "Aries";
case 5: return (day! >= 22) ? "Gemini" : "Taurus"
case 6: return (day! >= 22) ? "Cancer" : "Gemini";
case 7: return (day! >= 23) ? "Leo" : "Cancer";
case 8: return (day! >= 23) ? "Virgo" : "Leo";
case 9: return (day! >= 24) ? "Libra" : "Virgo";
case 10: return (day! >= 24) ? "Scorpio" : "Libra";
case 11: return (day! >= 23) ? "Sagittarius" : "Scorpio";
case 12: return (day! >= 22) ? "Capricorn" : "Sagittarius";
default: return ""
}
Duncan is right, I was writing you a sample code when he answered the question.....
//get date from your picker
NSDate *myDate = [datePickerControl date];
NSCalendar *gregorianCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComps = [gregorianCal components: (NSDayCalendarUnit | NSMonthCalendarUnit)
fromDate: myDate];
// Then use it
int month=[dateComps month];
int days=[dateComps day];
//I guess there is only two zodiac signs possilble for each month right?
switch (month)
{
case 1:
//compare the dates
if (days<=20)
{
//user is Capricorn
}
else
{
//user is Picses
}
break;
case 2:
break;
//you will have 12 cases and each case will have an if else with corect dates.....
default;
break;
}
Here is an answer for those using Swift. It is based upon Hendra Kusumah's tuple solution, but uses extensions and enums for a neater and more Swift-like answer.
Usage
let date = Date()
date.zodiacSign // Enum value e.g. .aquarius
date.zodiacSign.rawValue // String value e.g. "aquarius"
Note - If you wanted the string value to be capitalised or to appear different in another way, either manipulate the string using date.zodiacSign.rawValue.capitalized or edit the ZodiacSign enum cases e.g. case aquarius = "Aquarius"
Extension
extension Date {
var zodiacSign: ZodiacSign {
get {
let calendar = Calendar.current
let day = calendar.component(.day, from: self)
let month = calendar.component(.month, from: self)
switch (day, month) {
case (21...31, 1), (1...19, 2):
return .aquarius
case (20...29, 2), (1...20, 3):
return .pisces
case (21...31, 3), (1...20, 4):
return .aries
case (21...30, 4), (1...21, 5):
return .taurus
case (22...31, 5), (1...21, 6):
return .gemini
case (22...30, 6), (1...22, 7):
return .cancer
case (23...31, 7), (1...22, 8):
return .leo
case (23...31, 8), (1...23, 9):
return .virgo
case (24...30, 9), (1...23, 10):
return .libra
case (24...31, 10), (1...22, 11):
return .scorpio
case (23...30, 11), (1...21, 12):
return .sagittarius
default:
return .capricorn
}
}
}
}
Enum
enum ZodiacSign: String {
case aries
case taurus
case gemini
case cancer
case leo
case virgo
case libra
case scorpio
case sagittarius
case capricorn
case aquarius
case pisces
}
I have a problem with comparison two decimal values.
I have a text field that contains number like 0.123456 and NSNumber that contains 0.000001.
Maximum fraction digits of both is 6. Minimum - 0
I've tried to do it like that:
NSNumberFormatter *decimalFormatter = [[NSNumberFormatter alloc] init];
[decimalFormatter setNumberStyle: NSNumberFormatterDecimalStyle];
[decimalFormatter setMaximumFractionDigits:6];
double sum = [[decimalFormatter numberFromString:self.summTextField.text] doubleValue];
if (self.minSum != nil) {
if (sum < [self.minSum doubleValue]) {
return NO;
}
}
But i have a problem, that sometimes 0.123456 = 0,123455999... or 0,123456000000...01
For example #0.000001 doubleValue < #0.000001 doubleValue - TRUE.
How can I compare to NSNumber with a fractional part, to be sure that it will be correct?
Thanks in advance.
Create extension to decimal for rounding
extension Decimal {
func rounded(toDecimalPlace digit: Int = 2) -> Decimal {
var initialDecimal = self
var roundedDecimal = Decimal()
NSDecimalRound(&roundedDecimal, &initialDecimal, digit, .plain)
return roundedDecimal
}
}
let value1 = Decimal(2.34999999).rounded(toDecimalPlace: 4)
let value2 = Decimal(2.34999989).rounded(toDecimalPlace: 4)
print(value1.isEqual(to: value2))
this results in TRUE
You can round your value, if you worried about fractional part...
Something like this:
-(double)RoundNormal:(double) value :(int) digit
{
value = round(value * pow(10, digit));
return value / pow(10, digit);
}
And then compare it.
You can simply put the test otherwise if you do not want to bother much
if(abs(x-y) < 0.0001)
This should solve it:
NSNumberFormatter *decimalFormatter = [[NSNumberFormatter alloc] init];
[decimalFormatter setNumberStyle: NSNumberFormatterDecimalStyle];
[decimalFormatter setMaximumFractionDigits:6];
[decimalFormatter setMinimumFractionDigits:6];
[formatter setRoundingMode:NSNumberFormatterRoundHalfUp];
[formatter setRoundingIncrement:[NSNumber numberWithDouble:0.000001]]
Use the NSDecimalNumber class - see the guide Number and Values Programming Topics
This is how NSDecimal numbers are compared in iOS:
if ( [x compare:y] == NSOrderedSame ){
// If x is equal to y then your code here..
}
if([x compare:y] == NSOrderedDescending){
// If x is descendant to y then your code here..
}
if([x compare:y] == NSOrderedAscending){
// If x is ascendant to y then your code here..
}
Is there an API for this? Or maybe a better way of doing it?
Here's what I'm trying to acomplish:
In is a numeric string. Out, is a NSDecimalNumber
// this one is for US:
in: 1 out: 0.01
in: 12 out: 0.12
in: 123 out: 1.12
// a diferent locale might have a diferent maximumFractionDigits, like 1
in: 1 out: 0.1
in: 12 out: 1.2
in: 123 out: 12.3
// other locales might have 0, or 3 fraction digits.
Here's how I have it:
// Clear leading zeros
NSNumber *number = [formatter numberFromString:numericString];
numericString = [formatter stringFromNumber:number];
if (maximumFractionDigits == 0) {
return [NSDecimalNumber decimalNumberWithString:numericString];
}
else if (numericString.length <= _currencyFormatter.maximumFractionDigits) {
NSString *zeros = #"";
for (NSInteger i = numericString.length; i < maximumFractionDigits ; i++) {
zeros = [zeros stringByAppendingString:#"0"];
}
return [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"0.%#%#",zeros,numericString]];
} else {
NSString *decimalString = [NSString stringWithFormat:#"%#.%#",
[_rateInput substringToIndex:numericString.length - maximumFractionDigits],
[_rateInput substringFromIndex:numericString.length - maximumFractionDigits]];
return [NSDecimalNumber decimalNumberWithString: decimalString];
}
While this does seem to work, I was wondering if there is an API for this, or a more simple, less error prone way of doing it?