Getting the string value from a NSArray - objective-c

I have a NSArrayController and I when I get the selectedObjects and create a NSString with the value of valueForKey:#"Name" it returns
(
"This is still a work in progress "
)
and all I want to have is the text in the "" how would I get that? also, this my code:
NSArray *arrayWithSelectedObjects = [[NSArray alloc] initWithArray:[arrayController selectedObjects]];
NSString *nameFromArray = [NSString stringWithFormat:#"%#", [arrayWithSelectedObjects valueForKey:#"Name"]];
NSLog(#"%#", nameFromArray);
Edit: I also have other strings in the array

When you call valueForKey: on an array, it calls valueForKey: on each of the elements contained in the array, and returns those values in a new array, substituting NSNull for any nil values. There's also no need to duplicate the selectedObjects array from the controller because it is immutable anyway.
If you have multiple objects in your array controller's selected objects, and you want to see the value of the name key of all items in the selected objects, simply do:
NSArray *names = [[arrayController selectedObjects] valueForKey:#"name"];
for (id name in names)
NSLog (#"%#", name);
Of course, you could print them all out at once if you did:
NSLog (#"%#", [[arrayController selectedObjects] valueForKey:#"name"]);
If there's only one element in the selectedObjects array, and you call valueForKey:, it will still return an array, but it will only contain the value of the key of the lone element in the array. You can reference this with lastObject.
NSString *theName = [[[arrayController selectedObjects] valueForKey:#"name"] lastObject];
NSLog (#"%#", theName);

Related

Objective C should these two return the same value

What is the difference of notificationIdToCancle1 and notificationIdToCancle2 in the code below:
NSDictionary* parameters = (NSDictionary* )parametersObject;
if (parameters != nil) {
NSString* notificationIdToCancle1 = (NSString* )[parameters objectForKey:#"id"];
NSString *notificationIdToCancle2 = [NSString stringWithFormat:#"%#",[parameters valueForKey:#"id"]];
}
Shouldn't both contain the same value?
NSString* notificationIdToCancle1 = (NSString* )[parameters objectForKey:#"id"];
This line is grabbing the object in the dictionary, casting it to an NSString whether it is or isn't.
[NSString* stringWithFormat:#"%#",[parameters valueForKey:#"id"]];
This line, I think you have a mistake, you probably don't want the first '*'. You also probably want to call 'objectForKey:' rather than 'valueForKey:'. objectForKey: will return the entry in the dictionary, while valueForKey: will use Key Value Coding to return a value.
So:
[NSString stringWithFormat:#"%#",[parameters objectForKey:#"id"]];
This takes the object in the dictionary, runs 'description' on it which returns an NSString instance. So you definitely get an NSString instance out of it.

filter dictionary array by property that matches a different array

I have two arrays and I'm trying to filter the first (array1) with a matching property that exists in a second array (array2). The first array is a dictionary array with key 'name'. The second array is an array of objects with property 'name'. Is it possible to filter contents of 'array1' and display only those that have a matching 'name' found in 'array2'?
I've tried:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"name == #%",self.array2];
NSArray *results = [array1 filteredArrayUsingPredicate:pred];
NSLog(#"The results array is %#", results);
Rather than '==' I've tried a mix of 'IN' and '#K' and 'self' but it either crashes or results are 0.
NSPredicate *pred = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [[array2 valueForKey:#"name"] containsObject:[evaluatedObject objectForKey:#"name"]];
}];
This should work with IN:
NSArray *matchSet = [self.array2 valueForKey:#"name"];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"name IN #%",matchSet];
Typed in Safari.
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-215891
Here's a quick example of how you could accomplish this:
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSArray *arrayOne = #[#{#"name": #"Alvin"}, #{#"name": #"Brian"}, #{#"name": #"Charlie"}];
BMPPerson *alvin = [[BMPPerson alloc] initWithName:#"Alvin"];
BMPPerson *charlie = [[BMPPerson alloc] initWithName:#"Charlie"];
NSArray *arrayTwo = #[alvin, charlie];
NSArray *values = [arrayTwo valueForKey:#"name"];
NSMutableArray *filteredValues = [NSMutableArray array];
[arrayOne enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *name = [obj valueForKey:#"name"];
if ([values containsObject:name]) {
[filteredValues addObject:name];
}
}];
NSLog(#"%#", filteredValues);
}
return 0;
}
In the example, arrayOne is an NSArray of NSDictionary objects. Each object has a key of name.
The objects contained in arrayTwo are a basic NSObject subclass that has a name property.
To get the values of the name properties for all of the objects in arrayTwo we make use of the key-value coding method -valueForKey: which calls -valueForKey: on each object in the receiver and returns an array of the results.
We then create an NSMutableArray to hold the filtered results from arrayOne.
Next we enumerate the objects in arrayOne using the -enumerateObjectsUsingBlock: method. In this example, we know that the obj argument is an NSDictionary that has a key of name. Instead of casting to an NSDictionary and calling -objectForKey: we can simply call -valueForKey: and store the value in our local variable name. We then check to see if name is in the values array and if it is, add it to our filteredValues.

obj-c fetching strings from array

i'm new to obj-c (this is my first day class eheh) and i'm trying to change a label with a random string from a multidimensional array. plus, every time the button is hitten you switch the array. i know it's a bit odd eheh… this is the IBAction:
UIButton *button = (UIButton *)sender;
NSMutableArray *firstArray = [NSMutableArray array];
[firstArray addObject:#"foo"];
NSMutableArray *secondArray = [NSMutableArray array];
[secondArray addObject:#"bar"];
NSMutableArray *frasi = [NSMutableArray array];
[frasi addObject:firstArray];
[frasi addObject:secondArray];
NSMutableArray *array = [NSMutableArray arrayWithObjects:[frasi objectAtIndex:[button isSelected]], nil];
NSString *q = [array objectAtIndex: (arc4random()% [array count] )];
NSString *lab = [NSString stringWithFormat:#"%#", q];
self.label.text = lab;
all works, but the new label is
( "foo" )
instead of just foo (without quotes)... probably i mess in the last block of code...
ty
So, you create 2 mutable arrays, then add them to a new mutable array frasi. Then you get one of those two arrays and use it as the single element (because you use arrayWithObjects: instead of arrayWithArray:) of a new array array.
So array is an array that contains a single array element (instead of an array of strings as you may believe).
When you get an object from array, it's always the same single object that was used to initialize it: either firstArray or secondArray.
So you get an array of strings where you expect a string. When using stringWithFormat:, the specifier %# is replaced with the string description of that object.
A string returns itself as its own description. But the description of an array is the list of all its elements separated with commas and surrounded by parenthesis, which is why you get ( "foo" ).
So instead or creating unneeded arrays, you may just replace all the 8th last lines with this:
NSArray *array = [button isSelected] ? secondArray : firstArray;
self.label.text = [array objectAtIndex:arc4_uniform([array count])];
Actually u have array within array
Replace this line with yours:
NSString *q = [[array objectAtIndex: (arc4random()% [array count] )] objectAtIndex:0];

Application crashes when using NSMutableString

in a header file I defined
NSMutableArray *numbers;
In the implementation I initialize this array first in the init method
numbers = [[NSMutableArray alloc] init];
I add strings to this array
[numbers insertObject:number atIndex:[numbers count]];
But when I access the array like this in another method
NSLog(#"%#", [numbers count]);
the application crashes. Any idea why this happens?
You are wrong here -
NSLog(#"%#", [numbers count]);
Array count is an integer value. Use %d instead of %# to print integer.
NSLog(#"%d", [numbers count]);
Your format string doesn't match the type of the second parameter.
[numbers count] returns an integer, not an object.
The " %#" format specifier indicates that the corresponding argument is an object, and that object will be sent a -description message. The string returned from that message expression will be inserted in place of the "%#". Your app crashes because it tries to send a message to an invalid receiver.

How to print a single array element in Objective-C?

How to print a array element at particular index in Objective-C? My code looks like this:
NSString *String=[NSString StringWithContentsOFFile:#"/User/Home/myFile.doc"];
NSString *separator = #"\n";
NSArray *array = [String componetntsSeparatedByString:separator];
NSLog(#"%#",array);
I'm able to print the full contents of an array at once, but I want to assign the element at each index into a string, like...
str1=array[0];
str2=array[1];
str3=array[0];...this continues
How do I do this?
You want the objectAtIndex: method. Example:
NSString *str1 = [array objectAtIndex:0];
NSString *str2 = [array objectAtIndex:1];
NSString *str3 = [array objectAtIndex:2];
From the documentation:
objectAtIndex:
Returns the object located at index.
- (id)objectAtIndex:(NSUInteger)index
Parameters
index
An index within the bounds of the receiver.
Return Value
The object located at index.
Discussion
If index is beyond the end of the array (that is, if index is greater than or equal to the value returned by count), an NSRangeException is raised.
if this is only for debugging, you could try using po <> in the gdb.
As of clang version 3.3, you can use the [index] notation, so
NSString *str1 = array[0];
would work now. See here for details.