Construct NSString from the description method of each NSArray item? - objective-c

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);

Related

How to extract selected attribute(s) from an NSArray of Core Data entity objects and form into a joint string?

Normally, if I have an NSArray of just NSString's, I can use the NSArray's method:
- (NSString *)componentsJoinedByString:(NSString *)separator
to get a String (like "John,David,Peter"). However, if I have an NSArray of Core Data Entity objects and I just need to to get 1 attribute within (say, the "name" attribute only of each entity object), what is the easiest way to do this?
The Core Data entity object can have many attributes (name, phone, birthdate), but I just want a string like "John,David,Peter".
The following will do a fetch for only the name properties of the Person objects:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Person"];
request.propertiesToFetch = #[#"name"];
request.resultType = NSDictionaryResultType;
NSArray *array = [managedObjectContext executeFetchRequest:request error:nil];
NSString *names = [[array valueForKey:#"name"] componentsJoinedByString:#","];
NSLog(#"%#", names);
You need to set the resultType to NSDictionaryResultType otherwise it will ignore propertiesToFetch. The result from the fetch is an array of Dictionaries. Using valueForKey and componentsJoinedByString will create a single string out of all the names.
Your best option is the straightforward one of building up a NSMutableString by iterating over the items in you array and asking each one for its name to use in appendString:. You could add a description method to the entity object and then use the method you mentioned but description is used for other things and would probably cause conflicts.
// Assuming you have the list of entities - NSArray *entityObjects
NSMutableString *nameAttributes = [[NSMutableString alloc] init];
for(int i = 0; i < [entityObjects count]-1; i++){
[nameAttributes appendString:[NSString stringWithFormat:#"%#, ", [entityObjects objectAtIndex:i].name]];
}
[nameAttributes appendString:[NSString stringWithFormat:#"%#", [entityObjects lastObject].name]];
If you have an NSArray *objects of Core Data objects, each of which has a name attribute, then you can use
NSArray *names = [objects valueForKey:#"name"];
to get a new array with all the names, which you can then concatenate with
NSString *allNames = [names componentsJoinedByString:#","];
You can simply do like that,
NSString *toCollectString =#"";
for(int k =0;k<self.arrayHoldingObjects.count;k++)
{
ModelName *model = [self.arrayHoldingObjects objectAtIndex:k];
NSString *str = model.name;
toCollectString = [toCollectString stringByAppendingString:str];
}
You will get the names in toCollectString.

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 put elements from NSMutableArray into C char?

I have a NSMutableArray and I need to sort its elements into separate C char.
How to accomplish that? Or is it better to put the elements into NSStrings?
I've tried this, and it crashes when I try to log the result:
NSMutableArray *array = [[NSMutableArray alloc] init];
... do something to fill the array ...
NSString *string;
string = [array objectAtIndex:0];
NSLog(#"String: %#", string);
*I really prefer putting the elements of the array into C char, because I already have some woking code using char instead of NSStrin*g.
Thanks!
Dont see any specific reason to convert NSString to C chars. To sort an array full of NSStrings try this method -
NSMutableArray *array = [[NSMutableArray alloc] init];
sortedArray = [array sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *string = [sortedArray objectAtIndex:0];
NSLog(#"String: %#", string);

Look for similar strings in NSArray

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];

Objective-C string arrays

I have a string array as such:
NSArray *names;
names = [NSArray arrayWithObjects:
#"FirstList",
#"SecondList",
#"ThirdList",
nil];
I'm trying to assign an element of this string array to a string variable as such:
NSString *fileName = names[0]; // "Incompatible types in initialization"
or with casting
NSString *fileName = (NSString)names[0]; // "Conversion to non-scalar type requested"
I'm trying to do this, so I can use the string in a method that takes a string as an argument, such as:
NSString *plistPath = [bundle pathForResource:filetName ofType:#"plist"];
Is there no way to assign an element of a string array to a string variable?
Update from 2014: The code in this post actually would work these days since special syntactic support has been added to the framework and compiler for indexing NSArrays like names[0]. But at the time this question was asked, it gave the error mentioned in this question.
You don't use C array notation to access NSArray objects. Use the -objectAtIndex: method for your first example:
NSString *fileName = [names objectAtIndex:0];
The reason for this is that NSArray is not "part of Objective-C". It's just a class provided by Cocoa much like any that you could write, and doesn't get special syntax privileges.
NSArray is a specialized array class unlike C arrays. To reference its contents you send it an objectAtIndex: message:
NSString *fileName = [names objectAtIndex:0];
If you want to perform an explicit cast, you need to cast to an NSString * pointer, not an NSString:
NSString *fileName = (NSString *)[names objectAtIndex:0];
With the new Objective-C literals is possible to use:
NSString *fileName = names[0];
So your code could look like this:
- (void)test5518658
{
NSArray *names = #[
#"FirstList",
#"SecondList",
#"ThirdList"];
NSString *fileName = names[0];
XCTAssertEqual(#"FirstList", fileName, #"Names doesn't match ");
}
Check Object Subscripting for more information.