For text bozo__foo!!bar.baz, how to split an NSString containing this into (bozo, foo, bar, baz)?
That is, separe it in components with strings (delimiters) __, !! and ..
You can split the strings using NSCharacterSet. Try this
NSString *test=#"bozo__foo!!bar.baz";
NSString *sep = #"_!.";
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:sep];
NSArray *temp=[test componentsSeparatedByCharactersInSet:set];
NSLog(#"temp=%#",temp);
I'm aware that this question has already been answered but this is a way to separate strings using multiple strings. This is a category to NSString.
- (NSArray<NSString *> *)componentsSeparatedByStrings:(NSArray<NSString *> *)separators
{
NSMutableArray<NSString *> *components = [[NSMutableArray alloc] init];
unichar buffer[self.length + 1];
NSInteger currentOrigin = 0;
NSInteger currentLength = 0;
[self getCharacters:buffer];
for(NSInteger i = 0; i < self.length; i++)
{
unichar currentChar = buffer[i];
currentLength++;
for(NSInteger n = 0; n < separators.count; n++)
{
NSString *currentDivider = [separators objectAtIndex:n];
if(currentDivider.length == 0)
{
return #[self];
}
else if(currentDivider.length > 1)
{
BOOL goodMatch = NO;
for(NSInteger x = 0; x < currentDivider.length; x++)
{
unichar charInDivider = [currentDivider characterAtIndex:x];
if(charInDivider == currentChar)
{
goodMatch = YES;
}
else
{
goodMatch = NO;
break;
}
if(goodMatch == YES && ((x + 1) != currentDivider.length))
{
i++;
currentLength++;
currentChar = buffer[i];
}
}
if(goodMatch == YES)
{
NSRange newComponentRange = NSMakeRange(currentOrigin, (currentLength - currentDivider.length));
NSString *newComponent = [self substringWithRange:newComponentRange];
currentOrigin = (i + 1);
currentLength = 0;
[components addObject:newComponent];
NSLog(#"%#", components);
}
}
else // If current divider is only one character long.
{
if([currentDivider characterAtIndex:0] == currentChar)
{
NSRange newComponentRange = NSMakeRange(currentOrigin, (currentLength - 1));
NSString *newComponent = [self substringWithRange:newComponentRange];
currentOrigin = (i + 1);
currentLength = 0;
[components addObject:newComponent];
break;
}
}
}
// Handle the end of the string.
if((i + 1) == self.length)
{
NSRange newComponentRange = NSMakeRange(currentOrigin, currentLength);
NSString *newComponent = [self substringWithRange:newComponentRange];
currentOrigin = 0;
currentLength = 0;
[components addObject:newComponent];
}
}
return components;
}
Example: "ABCD__EFGHI__JKLMNOP-QRST.UV_WXYZ"
NSLog(#"%#", [test componentsSeparatedByStrings:#[#"__", #"-", #"."]]);
Log Result: "(ABCD, EFGHI, JKLMNOP, QRST, "UV_WXYZ")"
NSString *text = #"bozo__foo!!bar.baz";
NSArray *split1 = [text componentsSeparatedByString:#"__"];
NSArray *split2 = [[split1 lastObject] componentsSeparatedByString:#"!!"];
NSArray *split3 = [[split2 lastObject] componentsSeparatedByString:#"."];
NSLog(#"%#, %#, %#, %#", split1[0], split2[0], split3[0], split3[1]);
More functional solution is to apply -componentsSeparatedByString: recursively, for each component, which was derived during previous separator application:
NSString Category
- (NSMutableArray<NSString *> *)gvr_componentsSeparatedByStrings:(NSArray<NSString *> *)separators {
if (separators.count == 0) {
return [NSMutableArray arrayWithObject:self];
}
NSString *separator = [separators firstObject];
NSArray *reducedSeparators = [separators gvr_arrayByRemovingFirstObject];
NSArray *components = [self componentsSeparatedByString:separator];
NSMutableArray *result = [NSMutableArray new];
for (NSString *component in components) {
NSMutableArray *subResult = [component gvr_componentsSeparatedByStrings:reducedSeparators];
[result addObjectsFromArray:subResult];
}
return result;
}
NSArray Category
- (NSArray *)gvr_arrayByRemovingFirstObject {
NSMutableArray *result = [NSMutableArray new];
for (NSInteger i = 1; i < self.count; i++) {
[result addObject:self[i]];
}
return [result copy];
}
I solved it for my project by looking for the longest separator, replacing the others with this one, then do the separation on the only one left.
Try this:
NSString *test = #"bozo__foo!!bar.baz";
test = [test stringByReplacingOccurrencesOfString:#"!!" withString:#"__"];
test = [test stringByReplacingOccurrencesOfString:#"." withString:#"__"];
NSArray<NSString *> *parts = [test componentsSeparatedByString:#"__"];
Related
i have test array with objects structure - Group with (NSMutableArray)items, and i save group in YapDatabase
-(void)parseAndSaveJson:(id) json withCompleteBlock:(void(^)())completeBlock{
NSMutableArray *groupsArray = (NSMutableArray *)json;
if (groupsArray != nil) {
YapDatabaseConnection *connectnion = [[DatabaseManager sharedYapDatabase] newConnection];
[connectnion asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
for (int groupIndex = 0; groupIndex < [groupsArray count]; groupIndex ++) {
LocalGroupsExercise *localGroup = [[LocalGroupsExercise alloc] init];
localGroup.name = groupsArray[groupIndex][LOCAL_GROUPS_NAME];
localGroup.tagColor = groupsArray[groupIndex][LOCAL_GROUPS_TAG_COLOR];
localGroup.idGroup = [groupsArray[groupIndex][LOCAL_GROUPS_ID_GROUP] intValue];
if (groupsArray[groupIndex][LOCAL_GROUPS_EXERCISES] != nil) {
NSMutableArray *exerciseArray = (NSMutableArray *)groupsArray[groupIndex][LOCAL_GROUPS_EXERCISES];
for (int exerciseIndex = 0; exerciseIndex < [exerciseArray count]; exerciseIndex ++) {
LocalExercise *localExercise = [[LocalExercise alloc] init];
localExercise.name = exerciseArray[exerciseIndex][EXERCISE_NAME];
localExercise.exerciseId = [exerciseArray[exerciseIndex][LOCAL_EXERCISE_ID_EXERCISE] intValue];
localExercise.groupId = localGroup.idGroup;
localExercise.type = [exerciseArray[exerciseIndex][EXERCISE_TYPE] intValue];
localExercise.minWeight = [exerciseArray[exerciseIndex][EXERCISE_MIN_WEIGHT] floatValue];
localExercise.maxWeight = [exerciseArray[exerciseIndex][EXERCISE_MAX_WEIGHT] floatValue];
localExercise.minReps = [exerciseArray[exerciseIndex][EXERCISE_MIN_REPS] intValue];
localExercise.maxReps = [exerciseArray[exerciseIndex][EXERCISE_MAX_REPS] intValue];
localExercise.minTimer = [exerciseArray[exerciseIndex][EXERCISE_MIN_TIMER] intValue];
localExercise.maxTimer = [exerciseArray[exerciseIndex][EXERCISE_MAX_TIMER] intValue];
localExercise.timeRelax = [exerciseArray[exerciseIndex][EXERCISE_RELAX_TIME] intValue];
[localGroup.exercises addObject:localExercise];
}
}
[transaction setObject:localGroup forKey:[NSString stringWithFormat:#"%d", localGroup.idGroup] inCollection:LOCAL_GROUPS_CLASS_NAME];
}
YapDatabaseConnection *connectnion = [[DatabaseManager sharedYapDatabase] newConnection];
[connectnion readWithBlock:^(YapDatabaseReadTransaction *transaction) {
LocalGroupsExercise *group = [transaction objectForKey:#"2" inCollection:LOCAL_GROUPS_CLASS_NAME];
NSLog(#"%#", group.name);
NSLog(#"%#", group.tagColor);
NSLog(#"%#", group.exercises);
}];
} completionBlock:^{
completeBlock();
}];
}
}
+ (YapDatabaseView *)setupDatabaseViewForShowGroupsGyms{
YapDatabaseViewGrouping *grouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
if ([object isKindOfClass:[LocalGroupsExercise class]]) {
LocalGroupsExercise *groupExercise = (LocalGroupsExercise *)object;
return [NSString stringWithFormat:#"%#", groupExercise.name];
}
return nil;
}];
YapDatabaseViewSorting *sorting = [YapDatabaseViewSorting withObjectBlock:^NSComparisonResult(YapDatabaseReadTransaction *transaction, NSString *group, NSString *collection1, NSString *key1, LocalGroupsExercise *obj1, NSString *collection2, NSString *key2, LocalGroupsExercise *obj2) {
return [obj1.name compare:obj2.name options:NSNumericSearch range:NSMakeRange(0, obj1.name.length)];
}];
YapDatabaseView *databaseView = [[YapDatabaseView alloc] initWithGrouping:grouping sorting:sorting versionTag:#"0"];
return databaseView;
}
[[DatabaseManager sharedYapDatabase] registerExtension:self.databaseGroupView withName:LOCAL_GROUPS_CLASS_NAME];
[_connection beginLongLivedReadTransaction];
self.mappingsGroup = [[YapDatabaseViewMappings alloc] initWithGroupFilterBlock:^BOOL(NSString *group, YapDatabaseReadTransaction *transaction) {
return true;
} sortBlock:^NSComparisonResult(NSString *group1, NSString *group2, YapDatabaseReadTransaction *transaction) {
return [group1 compare:group2];
} view:LOCAL_GROUPS_CLASS_NAME];
[_connection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[self.mappingsGroup updateWithTransaction:transaction];
}];
The problem is that the group be NSMutabblArray and I want to see the objects in the table of the array, but [self.mappingsGroup numberOfItemsInSection:section] return only one items in group
You need to configure YapDatabase to use Mantle. By default, it will use NSCoding. (Which is why you're seeing an error about "encodeWithCoder:", as that method is part of NSCoding.)
Take a look at YapDatabase's wiki article entitled "Storing Objects", which talks about how it uses the serializer/deserializer blocks: https://github.com/yaptv/YapDatabase/wiki/Storing-Objects
Basically, when you alloc/init your YapDatabase instance, you'll want to pass a serializer & deserializer block that uses Mantle to perform the serialization/deserialization.
Also, see the various init methods that are available for YapDatabase: https://github.com/yaptv/YapDatabase/blob/master/YapDatabase/YapDatabase.h
So I'm making a biginteger program, and I'm having a problem with adding two arrays that aren't the same length. The problem I'm having is with the add method. If I'm iterating through an array is there any way to test if element is out of bounds. I've tried testing if the element in a is equal to nil, but I still get the exception. Any help would be great thanks.
#import <Foundation/Foundation.h>
#import "MPInteger.h"
#implementation MPInteger
{
}
-(id) initWithString: (NSString *) x
{
self = [super init];
if (self) {
intString = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[intString addObject:ch];
}
}
return self;
}
-(NSString *) description
{
return self.description;
}
- (MPInteger *) add: (MPInteger *) x {
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray array];
NSInteger arrayCount;
if (a < b) {
arrayCount = [b count];
} else {
arrayCount = [a count];
}
int num = 10;
int carry = 1;
NSNumber *total;
NSNumber *carrySum;
for (int i = 0; i < arrayCount; i++) {
if (a[i] == nil) {
total = #([b[i] intValue]);
[c addObject:total];
} else if (b[i] == nil) {
total = #([a[i] intValue]);
[c addObject:total];
} else {
total = #([a[i] intValue] + [b[i] intValue]);
[c addObject:total];
}
}
for (NSInteger j = [c count]-1; j >=0; j--) {
if ([c[j] intValue] >= num) {
total = #([c[j] intValue] - num);
carrySum = #([c[j-1] intValue] + carry);
[c replaceObjectAtIndex:j withObject:total];
[c replaceObjectAtIndex:j-1 withObject: carrySum];
}
}
NSString *str = [c componentsJoinedByString:#""];
NSLog(#"%#", str);
return x;
}
-(MPInteger *) multiply: (MPInteger *) x
{
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray array];
NSMutableArray *sum = [NSMutableArray array];
NSNumber *total;
NSNumber *carrySum;
int num = 10;
NSNumber *endZero = 0;
NSInteger bottomCount = [b count]-1;
while (bottomCount != -1) {
for (int i = 0; i < [a count]; i++) {
total = #([a[i] intValue] * [[b objectAtIndex:bottomCount] intValue]);
if (bottomCount == [b count] -1) {
[c addObject:total];
} else {
[c replaceObjectAtIndex:i withObject:total];
}
}
for (NSInteger j = [c count]-1; j>=0; j--) {
NSString *carry = [NSString stringWithFormat:#"%d", [c[j] intValue]];
NSString *carry2 = [carry substringToIndex:1];
int carryFinal = [carry2 intValue];
NSString *carry3 = [carry2 stringByAppendingString:#"0"];
int carry4 = [carry3 intValue];
if ([c[j] intValue] >= num) {
total = #([c[j] intValue] - carry4);
carrySum = #([c[j-1] intValue] + carryFinal);
[c replaceObjectAtIndex:j withObject:total];
[c replaceObjectAtIndex:j-1 withObject: carrySum];
} else {
if(j == 0) {
if (bottomCount == [b count] -1) {
bottomCount = bottomCount - 1;
NSString *str = [c componentsJoinedByString:#""];
[sum addObject: str];
} else {
[c addObject:#([endZero intValue])];
bottomCount = bottomCount - 1;
NSString *str = [c componentsJoinedByString:#""];
[sum addObject: str];
}
}
}
}
}
NSMutableArray *finalSum = [NSMutableArray array];
MPInteger *ele1;
MPInteger *ele2;
MPInteger *eleSum;
NSNumber *endZ= #(0);
[finalSum insertObject:endZ atIndex:0];
for (int k = 0; k < [sum count]; k++) {
NSString *str= [NSString stringWithFormat:#"%d", [sum[k] intValue]];
NSString *str2 = [NSString stringWithFormat:#"%d", [sum[k+1] intValue]];
ele1 = [[MPInteger alloc] initWithString:str];
ele2 = [[MPInteger alloc] initWithString:str2];
eleSum = [ele1 add: ele2];
NSLog(#"%#", eleSum);
}
NSLog(#"%#", sum);
return self;
}
Updated this
for (int i = 0; i < arrayCount; i++) {
if (a[i] == nil) {
total = #([b[i] intValue]);
[c addObject:total];
} else if (b[i] == nil) {
total = #([a[i] intValue]);
[c addObject:total];
} else {
total = #([a[i] intValue] + [b[i] intValue]);
[c addObject:total];
}
}
has now become:
NSMutableArray *c = a.count > b.count ? [a mutableCopy] : [b mutableCopy];
NSArray *shortestArray = a.count > b.count ? b : a;
[shortestArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSNumber *currentNumber, NSUInteger idx, BOOL *stop) {
c[idx] = #(currentNumber.integerValue + [c[idx] integerValue]);
NSLog(#"%#", c[idx]);
}];
What I think I need to do is every index that is in array a and not b or vise versa, is add beginning zeros, but I don't know how to do that.
I printed out what it does after each iteration and it gives:
2013-09-02 12:31:42.630 Asgn1[42471:303] 5
2013-09-02 12:31:42.632 Asgn1[42471:303] 3
2013-09-02 12:31:42.632 Asgn1[42471:303] 1
And a final answer of:
2013-09-02 12:31:42.633 Asgn1[42471:303] 353
For the code that is failing would it not be simpler to take a mutableCopy of the large array and then loop over the smaller array for the calculations?
Perhaps something like this:
NSMutableArray *c = a.count > b.count ? [a mutableCopy] : [b mutableCopy];
NSArray *shortestArray = a.count > b.count ? b : a;
[shortestArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSNumber *currentNumber, NSUInteger idx, BOOL *stop) {
c[idx] = #(currentNumber.integerValue + [c[idx] integerValue]);
}];
I need to substring to the 2nd comma in an NSString.
Input:
NSString *input = #"title, price, Camry, $19798, active";
Desired Output:
NSString *output = #"title, price";
Thanks!
UPDATE:
I have the following but the problem is it needs to skip the last comma:
NSString *output = [input rangeOfString:#"," options:NSBackwardsSearch];
Try this:
- (NSString *)substringOfString:(NSString *)base untilNthOccurrence:(NSInteger)n ofString:(NSString *)delim
{
NSScanner *scanner = [NSScanner scannerWithString:base];
NSInteger i;
for (i = 0; i < n; i++)
{
[scanner scanUpToString:delim intoString:NULL];
[scanner scanString:delim intoString:NULL];
}
return [base substringToIndex:scanner.scanLocation - delim.length];
}
this code should do what you need:
NSString *input = #"title, price, Camry, $19798, active";
NSArray *array = [input componentsSeparatedByString:#","];
NSArray *subArray = [array subarrayWithRange:NSMakeRange(0, 2)];
NSString *output = [subArray componentsJoinedByString:#","];
NSLog(output);
You could split -> splice -> join that string like this in objc:
NSString *input = #"title, price, Camry, $19798, active";
// split by ", "
NSArray *elements = [input componentsSeparatedByString: #", "];
// grab the subarray
NSArray *subelements = [elements subarrayWithRange: NSMakeRange(0, 2)];
// concat by ", " again
NSString *output = [subelements componentsJoinedByString:#", "];
You can try something like this:
NSArray *items = [list componentsSeparatedByString:#", "];
NSString result = #"";
result = [result stringByAppendingString:[items objectAtIndex:0]];
result = [result stringByAppendingString:#", "];
result = [result stringByAppendingString:[items objectAtIndex:1]];
You have to check you have at least two items if you want avoid an exception.
There's really nothing wrong with simply writing the code to do what you want. Eg:
int commaCount = 0;
int i;
for (i = 0; i < input.count; i++) {
if ([input characterAtIndex:i] == (unichar) ',') {
commaCount++;
if (commaCount == 2) break;
}
}
NSString output = nil;
if (commaCount == 2) {
output = [input substringToIndex:i];
}
You could create an NSString category to handle finding nth occurrences of any string. This is example is for ARC.
//NSString+MyExtension.h
#interface NSString(MyExtension)
-(NSString*)substringToNthOccurrence:(NSUInteger)nth
ofString:(NSString*)string;
-(NSString*)substringToNthOccurrence:(NSUInteger)nth
ofString:(NSString*)string
options:(NSStringCompareOptions)options;
#end
#implementation NSString(MyExtension)
-(NSString*)substringToNthOccurrence:(NSUInteger)nth
ofString:(NSString*)string
{
return [self substringToNthOccurrence:nth ofString:string options:0];
}
-(NSString*)substringToNthOccurrence:(NSUInteger)nth
ofString:(NSString*)string
options:(NSStringCompareOptions)options
{
NSUInteger location = 0,
strlength = [string length],
mylength = [self length];
NSRange range = NSMakeRange(location, mylength);
while(nth--)
{
location = [self rangeOfString:string
options:options
range:range].location;
if(location == NSNotFound || (location + strlength) > mylength)
{
return [self copy]; //nth occurrence not found
}
if(nth == 0) strlength = 0; //This prevents the last occurence from being included
range = NSMakeRange(location + strlength, mylength - strlength - location);
}
return [self substringToIndex:location];
}
#end
//main.m
#import "NSString+MyExtension.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
NSString *output = [#"title, price, Camry, $19798, active" substringToNthOccurrence:2 ofString:#","];
NSLog(#"%#", output);
}
}
*I'll leave it as an exercise for someone to implement the mutable versions.
Imagine you have two paths.
http://myserver.com/path1/path2 + /path1/path2/cache/image1.jpg = http://myserver.com/path1/path2/cache/image1.jpg
Both path strings could have more or less path components.
So what I'm asking is how to find the equal part in the strings and then remove that part from one of the strings?
You have no idea whether the "equal" parts are really equal or not. It's not uncommon to have, eg, paths like .../part1/part1/part1/...
For the mechanics of dealing with the paths, though, NSString has some nice methods -- lastPathComponent, stringByAppendindPathComponent, pathComponents, pathWithComponents, etc.
What about this:
- (NSString *)mergeStringsPrefix:(NSString *)prefix suffix:(NSString *)suffix
{
NSString *string = [NSString stringWithFormat:#"%#", prefix];
NSArray *prefixComponents = [prefix pathComponents];
NSArray *suffixComponents = [suffix pathComponents];
if ([prefixComponents count] == 0) return [string retain];
int rootIndex = [suffixComponents indexOfObject:#"/"];
int index = 1;
if (rootIndex == NSNotFound || rootIndex != 0) index = 0;
int startIndex = [prefixComponents indexOfObject:[suffixComponents objectAtIndex:index]];
if (startIndex == NSNotFound) return nil;
if ([suffixComponents count] - index < [prefixComponents count] - startIndex) return nil;
// fing length and check merge compatability
BOOL equalParts = YES;
for (int i=startIndex; i<[prefixComponents count] && equalParts; i++, index++)
{
NSString *el1 = [prefixComponents objectAtIndex:i];
NSString *el2 = [suffixComponents objectAtIndex:index];
if ([el1 compare:el2] != NSOrderedSame) equalParts = NO;
}
if (!equalParts) return nil;
// merge
for (int i=index; i<[suffixComponents count]; i++)
{
string = [string stringByAppendingFormat:#"/%#", [suffixComponents objectAtIndex:i]];
}
return [string retain];
}
This should do for you:
NSString* path1 = #"http://myserver.com/path1/path2";
NSString* path2 = #"/path1/path2/cache/image1.jpg";
NSMutableArray* path1Components = [NSMutableArray arrayWithArray:[path1 componentsSeparatedByString:#"/"]];
NSMutableArray* path2Components = [NSMutableArray arrayWithArray:[path2 componentsSeparatedByString:#"/"]];
[path2Components removeObjectAtIndex:0];
if ([path1Components containsObject:[path2Components objectAtIndex:0]]) {
NSUInteger objectIndex = [path1Components indexOfObject:[path2Components objectAtIndex:0]];
[path1Components removeObjectsInRange:NSMakeRange(objectIndex, [path1Components count]-objectIndex)];
[path1Components addObjectsFromArray:path2Components];
NSString* mergedPath = [path1Components componentsJoinedByString:#"/"];
NSLog(#"%#",mergedPath);
}
For parsing purposes it was necessary to replace commas inside quotas with space. I did not find and solution in NSString class and wrote this one.
It works, but I would like to know your opinion if there is more simple approach:
- (NSString *) replaceBetweenQuotesInString:(NSString*)line {
const char *buffer = [line UTF8String];
NSMutableIndexSet *evenIndexes = [NSMutableIndexSet indexSet];
NSMutableIndexSet *oddIndexes = [NSMutableIndexSet indexSet];
BOOL evenOdd = YES;
for (unsigned int i = 0; i < [line length]; i++) {
if (buffer[i] == '"'){
if (evenOdd)
[evenIndexes addIndex:i];
else
[oddIndexes addIndex:i];
evenOdd = !evenOdd;
}
}
if ([evenIndexes count] != [oddIndexes count] )
[evenIndexes removeIndex:[evenIndexes lastIndex]];
int totalRanges = (int) [evenIndexes count];
for (int i = 0; i < totalRanges; i++) {
NSRange range = NSMakeRange([evenIndexes firstIndex], [oddIndexes firstIndex] - [evenIndexes firstIndex]);
[evenIndexes removeIndex:[evenIndexes firstIndex]];
[oddIndexes removeIndex:[oddIndexes firstIndex]];
line = [line stringByReplacingOccurrencesOfString:#"," withString:#" " options:NSLiteralSearch range:range];
}
[evenIndexes removeAllIndexes];
[oddIndexes removeAllIndexes];
return line;
}
I have not tested this but since you do not seem to be concerned about escaped quotes:
NSMutableString* result = [[NSMutableString alloc] init];
NSArray* components = [line componentsSeparatedByString: #"\""];
for (int i = 0 ; i < [components count] ; ++i)
{
if (i % 2 == 0)
{
[result appendString: [components objectAtIndex: i]];
}
else
{
NSString* fixed = [[components objectAtIndex: i] stringByReplacingOccurrencesOfString: #","
withString: #" "];
[result appendFormat: #"\"%#\"", fixed];
}
}