patternMinor
Parsing Websites and transferring Data between Objects
Viewed 0 times
websitesobjectstransferringbetweenparsinganddata
Problem
I have a
Each
As an example, if I have a De Neve hall object corresponding to "Lunch", and the times were
breakfast (9-11) lunch (12-2) dinner (5-8)
then
The general algorithm is:
I'm using an open source DOM parser, and below is the code for extracting the text once I obtain the correct row. Specific concerns are dealing with "Closed" meals and a better way to pass data to
if (data[0] != [NSNull nu
DiningHall class that has the 3 properties: openingTime, closingTime, and nextMealOpeningTime, and I need to set these NSDate properties from the data from this website.Each
DiningHall object corresponds to a particular meal. For example, there is a separate "De Neve" dining hall object for breakfast, lunch, and dinner. As an example, if I have a De Neve hall object corresponding to "Lunch", and the times were
breakfast (9-11) lunch (12-2) dinner (5-8)
then
openingTime is 12pm, closingTime is 2pm, and nextMealOpeningTime is 5pm.The general algorithm is:
given a particular meal:
for each hall
in data, find row corresponding to hall
find column corresponding to current meal
parse text, convert toNSDate
pass 3 NSDate's to DiningHall as array
I'm using an open source DOM parser, and below is the code for extracting the text once I obtain the correct row. Specific concerns are dealing with "Closed" meals and a better way to pass data to
DiningHall class, but any optimizations will help.- (NSArray) getHourDataForRow:(TFHppleElement)row Meal:(NSString*)meal {
NSArray *meals = [row childrenWithTagName:@"td"];
NSArray *mealNames = [NSArray arrayWithObjects:@"breakfast", @"lunch", @"dinner", nil];
int index = [mealNames indexOfObject:meal]+1;
TFHppleElement *cell = meals[index];
NSArray *strong = [cell childrenWithTagName:@"strong"];
NSMutableArray *retArr = [NSMutableArray array];
NSString *opening = [strong[0] firstChildWithTagName:@"text"].content;
NSDate *openingAsDate = [self dateFromString:opening];
if (openingAsDate){
[retArr addObject:openingAsDate];
NSString *closing = [strong[1] firstChildWithTagName:@"text"].content;
[retArr addObject:[self dateFromString:closing]];
}
else{
[retArr addObject:[NSNull null]];
[retArr addObject:[NSNull null]];
}
if (index +1
In DiningHall class
- (void) setHoursFromData:(NSArray*)data {if (data[0] != [NSNull nu
Solution
For now, I will avoid commenting too much on
I will, however, comment on
First of all, you left brackets off of your
The rest of the method however.... can be completely replaced. There's a class called
First, we need this link. This lets us know what our date format string should look like. We have hours without a leading zero and in 12-hour format, minutes, we have minutes, and we have an am/pm symbol.
So our format string will look like this:
Our AM symbol is
- (NSArray) getHourDataForRow:(TFHppleElement)row Meal:(NSString*)meal as I think the real answer here is to look into NSXMLParser and see if that will work for you. Other than that, for now I'll simply comment that your spacing is inconsistent and you should work in cleaning that up to make the code more readable.I will, however, comment on
dateFromString:- (NSDate*) dateFromString:(NSString*)time {
if ([time isEqualToString:@"CLOSED"])
return nil;
NSArray *digits = [time componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
int hour = [digits[0] intValue];
hour+= (([time rangeOfString:@"pm"].location == NSNotFound) ? 0:12) ; //add 12 for pm
int minutes = [digits[1] intValue];
//format nsdate
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit ) fromDate:[NSDate date]];
[components setHour:hour];
[components setMinute:minutes];
return [calendar dateFromComponents:components];
}First of all, you left brackets off of your
if statement. This in combination with the awkward indentation leaves the code quite confusing. Despite being optional, curly braces should never be omitted.The rest of the method however.... can be completely replaced. There's a class called
NSDateFormatter which is made specifically for converting NSDate objects to NSString objects and vice versa.First, we need this link. This lets us know what our date format string should look like. We have hours without a leading zero and in 12-hour format, minutes, we have minutes, and we have an am/pm symbol.
So our format string will look like this:
@"h:mma"Our AM symbol is
@"am" and our PM symbol is @"pm". Now we have all the information we need to create our NSDateFormatter object:- (NSDate*) dateFromString:(NSString*)time {
if ([time isEqualToString:@"CLOSED"]) {
return nil;
} else {
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"h:mma"];
[df setAMSymbol:@"am"];
[df setPMSymbol:@"pm"];
return [df dateFromString:time];
}
}Code Snippets
- (NSDate*) dateFromString:(NSString*)time {
if ([time isEqualToString:@"CLOSED"])
return nil;
NSArray *digits = [time componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
int hour = [digits[0] intValue];
hour+= (([time rangeOfString:@"pm"].location == NSNotFound) ? 0:12) ; //add 12 for pm
int minutes = [digits[1] intValue];
//format nsdate
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit ) fromDate:[NSDate date]];
[components setHour:hour];
[components setMinute:minutes];
return [calendar dateFromComponents:components];
}- (NSDate*) dateFromString:(NSString*)time {
if ([time isEqualToString:@"CLOSED"]) {
return nil;
} else {
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"h:mma"];
[df setAMSymbol:@"am"];
[df setPMSymbol:@"pm"];
return [df dateFromString:time];
}
}Context
StackExchange Code Review Q#57795, answer score: 4
Revisions (0)
No revisions yet.