Look for similar strings in NSArray - objective-c

Does NSArray have the capability of matching a string in an array with the closest representation of that string in another array?
For example:
NSString *search = #"apple p";
NSArray *array = [[NSArray alloc]initWithObjects:#"apple",#"apple pie",#"apple pies", #"apple juice", nil];
//Now we want to look for a similar string
[array ?];
The desired result should be: apple pie (most similar string). Any ideas how this could be done?

You could sort the array based on similarity, then retrieve the last element in the sorted array: the most similar string. Assuming you've defined some method similarityTo: in a category on NSString, something like the following should do the trick:
NSInteger compareStrings(id a, id b, void *context) {
int aSimilarity = [a similarityTo:(NSString *)context];
int bSimilarity = [b similarityTo:(NSString *)context];
return aSimilarity - bSimilarity;
}
// Retrieving the most similar string.
NSString *result = [[array sortedArrayUsingFunction:compareStrings
context:search] lastObject];

Related

How to change an array of strings into an array of integers in objC?

I retrieved an array of NSString-Objects (couples) out of another dynamic array valuesFirstdance. I know that the strings always contain integers. I need the values to be of type integer to sort the couplesarray. How would I change to type of every array value?
Thanks
couples = [valuesFirstdance allKeys];
NSArray* couples2 = [couples sortedArrayUsingSelector:#selector(intValue)];
To answer the question directly:
NSMutableArray *integerArray = [[NSMutableArray alloc] initWithCapacity:couples.count];
for (NSString *s in couples) {
[integerArray addObject:[NSNumber numberWithInteger:s.integerValue]];
}
But you could also do numeric sorting on the string values, e.g., using NSNumericSearch:
NSArray *sortedArray = [couples sortedArrayUsingComparator:^(NSString *o1, NSString *o2) {
return [o1 compare:o2 options:NSNumericSearch];
}];
NSString has a method called intValue - that is what you're looking for.
Of course, a better solution would be to have an array of NSNumbers instead of NSStrings.
You don't have to change the type of every array value to sort the couples array - look at this:
NSArray *sortedArray = [couplesArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSString *firstString = (NSString*) obj1;
NSString *secondString = (NSString*) obj2;
if([firsString integerValue]<[secondString integerValue])
return (NSComparisonResult) NSOrderedDescending;
else if([firsString integerValue]>[secondString integerValue])
return (NSComparisonResult) NSOrderedAscending;
return (NSComparisonResult) NSOrderedSame;
}];

Multidimensional Arrays in Objective C

I have an NSDictionary filled with data. If this was php it might be accessed by  something like:
$data = $array['all_items'][0]['name'];
How do I do something similar in objective c? ($array would be an NSDictionary)
The equivalent code in Objective-C is:
id data = [[[array objectForKey:#"all_items"] objectAtIndex:0] objectForKey:#"name"];
Note that objectForKey: is a method of NSDictionary, and objectAtIndex: is a method of NSArray.
A shortcut in Xcode 4.5, using LLVM 4.1, is:
id data = array[#"all_items"][0][#"name"];
Also note that if "array" is an NSDictionary instance and you want to get an array of all values in the dictionary, you use the allValues method of NSDictionary:
id data = [array allValues][0][#"name"];
Of course, allValues returns an unsorted array, so accessing the array by index is not very useful. More typically, you'd see:
for (NSDictionary* value in [array allValues])
{
id data = value[#"name"];
// do something with data
}
Unfortunately the objective-c version is not as elegant syntactically as the PHP version:
NSDictionary *array = ...;
NSArray *foo = [array objectForKey#"all_items"];
NSDictionary *bar = [foo objectAtIndex:0];
NSString *data = [bar objectForKey#"name"];
For brevity, you can do this on a single line as:
NSString *data = [[[array objectForKey#"all_items"] objectAtIndex:0] objectForKey#"name"];
You should use it,
NSString *value = [[multiArray objectAtIndex:1] objectAtIndex:0];
You can look the question here

Construct NSString from the description method of each NSArray item?

I have an NSArray, where each object contains a specific class called Card. Card has a description method. I want to join all objects in the array using the output of the description method, separated by spaces. Is there a simple to do this, without manually iterating the NSArray and manipulating NSString?
Something akin to the following made-up code?
NSArray *myArray = getCards(); // fetches 10 items or more
NSString *myString = [myArray joinUsingDescriptionMethodSeparatedBy:#" "];
or
NSString *myString = [NSString stringFromArrayDescriptionMethods:myArray separatedBy:#" "];
Naturally ,I could implement this myself but I suspect there could be something already present that does this.
I don't think that there is such a method. You can also implement it in a Category for NSString.
Sorry, I found this:
NSString * result = [[array valueForKey:#"description"] componentsJoinedByString:#""];
From the documentation:
Constructs and returns an NSString object that is the result of
interposing a given separator between the elements of the array.
- (NSString *)componentsJoinedByString:(NSString *)separator
Do this for description method of each NSArray item:
NSMutableString * result = [[NSMutableString alloc] init];
for (NSObject * obj in array)
{
[result appendString:[NSString stringWithFormat:#" %#"[obj description]]];
}
NSLog(#"The concatenated string is %#", result);

splitting nsstring and putting into tableview

I am trying to split the string into parts and insert into a table how should i do it?
I got an error for splitting of the array which is: -[__NSArrayI componentsSeparatedByString:]: unrecognized selector sent to instance 0x7a421e0
NSArray *BusRoute = alightDesc;
int i;
int count = [BusRoute count];
for (i = 0; i < count; i++)
{
NSDictionary *dic = [BusRoute objectAtIndex: i];
NSDictionary *STEPS = [dic valueForKey:#"STEPS"];
NSString *AlightDesc = [STEPS valueForKey:#"AlightDesc"];
NSLog(#"AlightDesc = %#", AlightDesc);
NSArray *aDescArray = [AlightDesc componentsSeparatedByString:#","];
NSLog(#"aDescArray = %#", aDescArray);
}
This is the string which I'm splitting, i got it from the NSLog
AlightDesc = (
"Block1",
"Block2",
"Block3"
)
please help I'm stuck thanks.
Objective C is not a strongly typed language. All you know for sure about [STEPS valueForKey:#"AlightDesc"] is that it will return an object (of type id). When you wrote NSString *AlightDesc = [STEPS valueForKey:#"AlightDesc"] the compiler did not complain because NSString * is a valid object type. Unfortunately there is a logic error in your code so that what was actually stored under the key #"AlightDesc" is an NSArray. As others have mentioned, NSArray does not respond to componentsSeparatedByString: so you get an error at runtime.
The easy fix for this is to correct your logic: Either store an NSString in the first place or treat what you get out as an NSArray. As #janusfidel mentioned you can use an NSArray perfectly well in a table by using objectAtIndex: to get the string for the entry you want.
In some more complicated cases you may not know what you will be getting out of a dictionary for a particular key. In that case in Objective C you can just ask the object:
id anObject = [STEPS valueForKey:#"AlightDesc"];
if ([anObject isKindOfClass:[NSString class]]) {
NSString *aString = (NSString *)anObject;
// Treat as a string ...
} else if ([anObject isKindOfClass:[NSString class]]) {
// Object is an array ...
Your NSString *AlightDesc should look like this
NSString *AlightDesc = "Block1,Block2,Block3";
NSArray *aDescArray = [AlightDesc componentsSeparatedByString:#","];
If your string is what you say it is
AlightDesc = ("Block1","Block2","Block3");
then your string is the problem because it's already broken up.

How to change the values of an NSString inside an NSMutableArray?

I have a mutable array of strings. For this example, let's say there are 2 strings in it.
The operation that I would like to do is take the first string and assign the value of the second string to it.
I was trying something like this:
- (void) someAction {
NSMutableArray * array = [[NSMutableArray alloc] initWithObjects: string1, string2, nil];
NSString * firstString = [array objectAtIndex:0];
NSString * secondString = [array objectAtIndex:1];
firstString = secondString;
}
But this method doesn't seem to work. As after I log these two strings, they don't change after the operation.
Please advise.
You can't change strings in an array like that.
The array contains pointers to the strings, and when you assign one string to another you are just swapping pointers around, not changing the string object that the array points to.
What you need to do to swap the string in the array is this:
- (void) someAction {
NSMutableArray * array = [[NSMutableArray alloc] initWithObjects: string1, string2, nil];
NSString * secondString = [array objectAtIndex:1];
[array replaceObjectAtIndex:0 withObject:secondString]; //replace first string with second string in the array
}