Created
August 23, 2015 03:25
-
-
Save bgulanowski/2105c214aa305800e9be to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSString+SnakeMaking.h | |
// Test | |
// | |
// Created by Brent Gulanowski on 2015-08-22. | |
// Copyright (c) 2015 Lichen Labs. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
@interface NSString (SnakeMaking) | |
- (NSString *)snakeCaseString; | |
- (NSString *)snakeCaseStringNumbersAsWords; | |
@end | |
@interface NSString (RegularExpressionMatching) | |
- (NSArray *)matchesForRegularExpression:(NSRegularExpression *)regex; | |
- (NSArray *)matchesForPattern:(NSString *)pattern; | |
- (NSString *)firstMatchForRegularExpression:(NSRegularExpression *)regex; | |
- (NSString *)firstMatchForPattern:(NSString *)pattern; | |
@end | |
@interface NSString (CamelCaseMatching) | |
- (NSArray *)camelCaseTokens; | |
- (NSArray *)camelCaseTokensNumbersAsWords; | |
@end | |
@interface NSString (Reversing) | |
- (NSString *)reversedString; | |
@end | |
@interface NSRegularExpression (SimplifiedMatching) | |
- (NSArray *)matchesInString:(NSString *)string; | |
- (NSTextCheckingResult *)firstMatchInString:(NSString *)string; | |
@end | |
@interface NSTextCheckingResult (StringMatching) | |
- (NSString *)stringForMatchInString:(NSString *)string; | |
@end | |
@interface NSArray (Mapping) | |
- (NSArray *)map:(id(^)(id object))block; | |
- (NSArray *)reversedArray; | |
@end | |
@interface NSMutableArray (Reversing) | |
- (void)reverse; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSString+SnakeMaking.m | |
// Test | |
// | |
// Created by Brent Gulanowski on 2015-08-22. | |
// Copyright (c) 2015 Lichen Labs. All rights reserved. | |
// | |
#import "NSString+SnakeMaking.h" | |
static NSString * const InitialTokenPattern = @"^[a-z][a-z0-9]*"; | |
static NSString * const InitialWordOrNumberTokenPattern = @"^[a-z]+|[0-9]+"; | |
static NSString * const ReverseSuccessiveTokenPattern = @"([A-Z]*|[a-z0-9]*)[A-Z]"; | |
static NSString * const ReverseSuccessiveWordOrNumberTokenPattern = @"([A-Z]*|[a-z]*)[A-Z]|[0-9]+"; | |
#define StringForSelector(sel) NSStringFromSelector(@selector(sel)) | |
@implementation NSString (SnakeMaking) | |
- (NSString *)snakeCaseString | |
{ | |
return [[[self camelCaseTokens] valueForKey:StringForSelector(lowercaseString)] componentsJoinedByString:@"_"]; | |
} | |
- (NSString *)snakeCaseStringNumbersAsWords | |
{ | |
return [[[self camelCaseTokensNumbersAsWords] valueForKey:StringForSelector(lowercaseString)] componentsJoinedByString:@"_"]; | |
} | |
@end | |
#pragma mark - | |
@implementation NSString (RegularExpressionMatching) | |
- (NSArray *)matchesForRegularExpression:(NSRegularExpression *)regex | |
{ | |
return [[regex matchesInString:self] map:^id(NSTextCheckingResult *result) { | |
return [result stringForMatchInString:self]; | |
}]; | |
} | |
- (NSArray *)matchesForPattern:(NSString *)pattern | |
{ | |
return [self matchesForRegularExpression:[NSRegularExpression regularExpressionWithPattern:pattern options:0 error:NULL]]; | |
} | |
- (NSString *)firstMatchForRegularExpression:(NSRegularExpression *)regex | |
{ | |
return [[regex firstMatchInString:self] stringForMatchInString:self]; | |
} | |
- (NSString *)firstMatchForPattern:(NSString *)pattern | |
{ | |
return [self firstMatchForRegularExpression:[NSRegularExpression regularExpressionWithPattern:pattern options:0 error:NULL]]; | |
} | |
@end | |
#pragma mark - | |
@implementation NSString (CamelCaseMatching) | |
+ (NSString *)initialTokenPatternNumbersAsWords:(BOOL)numbersAsWords | |
{ | |
return (numbersAsWords ? InitialWordOrNumberTokenPattern : InitialTokenPattern); | |
} | |
+ (NSString *)successiveTokenPatternNumbersAsWords:(BOOL)numbersAsWords | |
{ | |
return (numbersAsWords ? ReverseSuccessiveWordOrNumberTokenPattern : ReverseSuccessiveTokenPattern); | |
} | |
- (NSString *)firstCamelCaseTokenNumbersAsWords:(BOOL)numbersAsWords | |
{ | |
return [self firstMatchForPattern:[NSString initialTokenPatternNumbersAsWords:numbersAsWords]]; | |
} | |
- (NSArray *)successiveCamelCaseTokensNumbersAsWords:(BOOL)numbersAsWords | |
{ | |
return [[[self.reversedString matchesForPattern:[NSString successiveTokenPatternNumbersAsWords:numbersAsWords]] valueForKey:StringForSelector(reversedString)] reversedArray]; | |
} | |
- (NSArray *)camelCaseTokensTreatNumbersAsWords:(BOOL)numbersAsWords | |
{ | |
NSString *first = [self firstCamelCaseTokenNumbersAsWords:numbersAsWords]; | |
NSArray *rest = [self successiveCamelCaseTokensNumbersAsWords:numbersAsWords]; | |
return first.length > 0 ? [@[first] arrayByAddingObjectsFromArray:rest] : rest; | |
} | |
- (NSArray *)camelCaseTokens | |
{ | |
return [self camelCaseTokensTreatNumbersAsWords:NO]; | |
} | |
- (NSArray *)camelCaseTokensNumbersAsWords | |
{ | |
return [self camelCaseTokensTreatNumbersAsWords:YES]; | |
} | |
@end | |
#pragma mark - | |
@implementation NSString (Reversing) | |
- (NSString *)reversedString | |
{ | |
// This probably does terrible things to multi-byte characters :( | |
const char * str = [self UTF8String]; | |
unsigned long len = strlen(str); | |
char *rev = malloc(sizeof(char) * len + 1); | |
for (unsigned long i=0; i<len; ++i) { | |
rev[i] = str[len-i-1]; | |
} | |
rev[len] = '\0'; | |
NSString *reversedString = [NSString stringWithUTF8String:rev]; | |
free(rev); | |
return reversedString; | |
} | |
@end | |
#pragma mark - | |
@implementation NSRegularExpression (SimplifiedMatching) | |
- (NSArray *)matchesInString:(NSString *)string | |
{ | |
return [self matchesInString:string options:0 range:NSMakeRange(0, string.length)]; | |
} | |
- (NSTextCheckingResult *)firstMatchInString:(NSString *)string | |
{ | |
return [self firstMatchInString:string options:0 range:NSMakeRange(0, string.length)]; | |
} | |
@end | |
#pragma mark - | |
@implementation NSTextCheckingResult (StringMatching) | |
- (NSString *)stringForMatchInString:(NSString *)string | |
{ | |
return [string substringWithRange:self.range]; | |
} | |
@end | |
#pragma mark - | |
@implementation NSArray (Mapping) | |
- (NSArray *)reversedArray | |
{ | |
NSMutableArray *array = [self mutableCopy]; | |
[array reverse]; | |
return array; | |
} | |
- (NSArray *)map:(id(^)(id object))block | |
{ | |
NSMutableArray *array = [NSMutableArray array]; | |
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { | |
[array addObject:block(obj)]; | |
}]; | |
return array; | |
} | |
@end | |
#pragma mark - | |
@implementation NSMutableArray (Mapping) | |
- (void)reverse | |
{ | |
const NSUInteger count = self.count; | |
const NSUInteger mid = count/2; | |
for (NSUInteger i=0; i<mid; ++i) { | |
const NSUInteger opposite = count-i-1; | |
id temp = self[i]; | |
[self replaceObjectAtIndex:i withObject:self[opposite]]; | |
[self replaceObjectAtIndex:opposite withObject:temp]; | |
} | |
} | |
@end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment