How to access specific column in NSArray using Xcode - ios

I'm new to iOS programming. I'm trying to bind the specific field from the objects in an array to a UITableView. Here's my code:
NSArray *personInfo; //contains a record with fields: name, address, email
personInfo = [[PersonDatabase database] getAllPersons]; //pulling the record into array
From there, I'm trying to get the field "name" from my array.
cell.textLabel.text = [NSString stringWithFormat:#"%#", [personInfo objectAtIndex: indexPath.row] retain]

As it seems you have objects in your array, what you may be looking for is the -[NSArray valueForKey:] method (documentation here).
For example:
NSArray *names = [personInfo valueForKey:#"name"];
This should return you an array containing all of the names in the array.

Are you trying to create a 2D Array?. If so you'll need to call objectAtIndex: twice on it in a nested call, but since you're new I'd suggest breaking down to a few lines so you can see more clearly what is happening.
Also, theres heaps of good code snippets on google for dealing with NSArray and table view.

Please check that if you delcare your array in #interface file as
//////.h
NSArray *personInfo;
#property(nonatomic ,retain) NSArray personInfo;
and then
in #implementation file
add this line
#synthesize personInfo;
hope it works

Related

Check if NSMutableArray has a specific Object

I am trying to check if the NSMutableArray has a specific object, before adding the object to it, if exists then don't add.
i looked over many posts explaining how to do this, managed to implement it like this, but it always gives me that the object "doesn't exist", though i already added it !
//get row details into FieldLables Object
AllItemsFieldNames *FieldLabels = feedItems[row];
// object to hold single row detailes
AllItemsFieldNames *SelectedRowDetails = [[AllItemsFieldNames alloc] init];
SelectedRowDetails.item_name = FieldLabels.item_name;
//SelectedRowDetails.item_img = FieldLabels.item_img;
SelectedRowDetails.item_price = FieldLabels.item_price;
//NSLog(#"item has been added %#", SelectedRowDetails.item_name);
//NSLog(#"shopcartLength %lu", (unsigned long)SelectedFieldsNames.count);
if([SelectedFieldsNames containsObject:SelectedRowDetails])
{
NSLog(#"Already Exists!");
}
else
{
NSLog(#"Doesn't Exist!");
[SelectedFieldsNames addObject:SelectedRowDetails];
}
I can display all object from the NSMutableArray into a table, what i need to do in the above code is stop the addition of duplicate objects.
The first method listed on the NSArray documentation under the section "querying an array" is containsObject:. If it's not working, that suggests that your implementation of isEqual: is not correct. Make sure you follow the note in the documentation:
If two objects are equal, they must have the same hash value. This
last point is particularly important if you define isEqual: in a
subclass and intend to put instances of that subclass into a
collection. Make sure you also define hash in your subclass.
You might also consider using an NSSet since you can't add duplicates to that. Of course, this would also require a working version of isEqual:.
Sets are composed of unique elements, so this serves as a convenient way to remove all duplicates in an array.
here some sample,
NSMutableArray*array=[[NSMutableArray alloc]initWithObjects:#"1",#"2",#"3",#"4", nil];
[array addObject:#"4"];
NSMutableSet*chk=[[NSMutableSet alloc ]initWithArray:array]; //finally initialize NSMutableArray to NSMutableSet
array= [[NSMutableArray alloc] initWithArray:[[chk allObjects] sortedArrayUsingSelector:#selector(compare:)]]; //after assign NSMutableSet to your NSMutableArray and sort your array,because sets are unordered.
NSLog(#"%#",array);//1,2,3,4

iOS Arrays with custom classes to arrays with NSStrings

I have my own class with several properties and I have them in NSArray. I need to use them for method which takes NSArray of strings. So I am asking what is best aproach to get array with strings from my array which has custom classes. I can create second array and use it but I think there could be better way. I need to have it for different custom classes (from one, I want to use for example name property to new NSArray, in second title property and so).
I hope I explained well but I tried it once more on example:
NSArray *arrayWitCustomClasses = ... fill with custom classes;
// setValues method takes NSArray with NSStrings
// when arrayWithCustomClasses used it returns copyWithZone: error on custom class
[someObject setValues:[arrayWithCustomClasses toArrayWithStrings]];
As long as your object exposes the required values as NSString properties you can use the valueForKey method of NSArray.
For example
NSArray *arrayOfTitles=[arrayWithCustomClasses valueForKey:#"title"];
NSArray *arrayOfNames=[arrayWithCustomClasses valueForKey:#"name"];
Or
[someObject setValues:[arrayWithCustomClasses valueForKey:#"title"]];
and so on
NSMutableArray *strings = [NSMutableArray array];
for (NSObject *item in arrayWithCustomClasses) {
/* You can use a different property as well. */
[strings addObject:item.description];
}
[someObject setValues:strings.copy];
Like #Tim says, but you could shorten it by just using:
[someObject setValues:[arrayWithCustomClasses valueForKey:#"description"]];
Same result. One line of code.
Then implement the description method of your custom classes to return whatever properties and formatting you want.

Working with NSMutable Array that contain custom class object

I have an array - placeObjectsArray, that hold a lot of objects called place. Place is object of class PlaceHolder, in which i create different properties, filled with data:
self.place = [[PlaceHolder alloc]init];
// A lot of code here during parson XML with data
[self.placeObjectsArray addObject:self.place];
Header of this file look like this:
#interface PlaceHolder : NSObject
#property (strong, nonatomic) NSString *name;
#property (strong, nonatomic) NSString *description;
#property (strong, nonatomic) NSString *webPage;
It actually a container for an entity, each one hold data for name, description, image links etc. At now, i have array with place objects. What i want to, to manipulate with that objects inside an array. For example, how could i find all of data for specific "name"? (Name is one of properties in PlaceHolder class). How could i make an array that contain only names? How could i see in console 10 random "description"?
Any advice would be appreciated, thanks!
You're asking a bunch of separate questions.
First, how to select items in your array that match a particular name: Create an NSPredicate and use filteredArrayUsingPredicate. Google NSPredicate and you should find lots of examples.
Alternately you could use indexesOfObjectsPassingTest to get an index set of the items in the array that match your search criteria, and then use objectsAtIndexes: to turn the index set into a sub-array.
As for how to get all the names from the entries in your array, you can use a very cool trick in key value coding.
If you send an array the valueForKey message, it tries to fetch an item from each entry in the array using that key, and return them all in a new array. The code would look like this:
NSArray *names = [placeObjectsArray valueForKey #"name"];
Fetching 10 random descriptions is a little more complicated. You would need to write code that loops through the array, selecting 10 random items, and appends the description of each one into a new mutable array.
The trick there is to use arc4random_uniform to get a random index in your array:
NSUInteger random_index = arc4random_uniform(placeObjectsArray.count);
I leave the rest to you as a learning exercise.
If you want to fetch 10 random descriptions and make sure you never fetch the same description twice it's more complicated. You need to create a mutable copy of your array, then loop through the copy, fetching a random item, adding it's description to an array, and deleting the item from the array.
You can use NSPredicates:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name LIKE[cd] %#", nameSearch];
NSArray *filtered = [self.placeObjectsArray filteredArrayUsingPredicate:predicate];
You could iterate over your array looking for the PlaceHolder with a given name, like:
PlaceHolder *namedPlaceholder = nil;
for (PlaceHolder *placeholder in theArray) {
if ([placeholder.name isEqualToString:"whateverName"]) {
namedPlaceholder = placeholder;
break;
}
}
If you want to find PlaceHolders by name efficiently you might consider using a dictionary instead of an array. With a dictionary you can map names to objects, like:
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
myDictionary[#"foo"] = somePlaceholder;
myDictionary[#"bar"] = someOtherPlaceholder;
and retrieve them like:
PlaceHolder *somePlaceholder = myDictionary[#"foo"];
To get random objects from an array, I recommend getting random indexes using arc4random_uniform. This gives pseudo-random numbers with a better uniform distribution than rand or random, and does not require you to explicitly seed the sequence with srand or srandom.
PlaceHolder *randomPlaceholder = theArray[arc4random_uniform(theArray.count)];
or
const NSUInteger arrayCount = theArray.count;
for (NSUInteger j = 0; j < 10; j++) {
PlaceHolder *randomPlaceholder = theArray[arc4random_uniform(arrayCount)];
// Do something with randomPlaceholder.
}

UITableView Setup

I have an unsorted NSArray of names. I know how to build a static table, but I am not sure how to make a dynamic table that will have a section with the first letter of the name and then the names for that letter in put into each section. I know this sounds like a beginner level programming question, and well it is. Any help would be great. New to iOS programming so I am just trying to get a feel for everything.
You can do this easily with TLIndexPathTools using the block-based data model initializer:
NSArray *items = ...; // and array containing your unorganized data (items of type NSString assumed here)
TLIndexPathDataModel *dataModel = [[TLIndexPathDataModel alloc] initWithItems:items sectionNameBlock:^NSString *(id item) {
return [[((NSString *)item) substringToIndex:1] upperCaseString];
} identifierBlock:nil];
The sectionNameBlock argument is a block that returns the first letter of the given item, which the initializer uses to organize the data into sections. Then you'd use dataModel (instead of an array) in your data source and delegate methods using the various APIs like [dataModel numberRowsInSection:], [dataModel itemAtIndexPath:], [dataModel indexPathForItem:], etc.
Try running the "Blocks" sample project for a working example.

Search NSMutableArray

Hi what I want to do is search an NSMutable array for the string str or the header label in the view. If the word already exists in the array then I want to delete it. Otherwise I want to add it. Here's my code so far.
-(IBAction)add:(id)sender{
NSMutableArray *array=[[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"favorites"];
NSString *str=header.text;
}
See the manual: NSArray Class Reference

Resources