How to add multiple NSIndexPath into NSMutableArray - iphone

I am trying to add nsindexpath into an array .. i am able to add only one indexpath .if i try to add another indexpath into array ..the debugger shows only the newest indexpath .
for (int i = 0 ; i<[notificationArray count]; i++)
{
selectedSymptIndexPath = [NSIndexPath indexPathForRow:selectedSymptomIndex inSection:keyIndexNumber];
selectedSympIPArray = [[NSMutableArray alloc]init];
[selectedSympIPArray addObject:selectedSymptIndexPath];
}
even if i try to put [selectedSympIPArray addObject:selectedSymptIndexPath]; outside for loop still its adding only the newest indexpath rather than showing multiple indexpaths

You are alloc init'ing the array every time in the loop, dont do that.
Try this:
selectedSympIPArray = [[NSMutableArray alloc]init];
for (int i = 0 ; i<[notificationArray count]; i++)
{
selectedSymptIndexPath = [NSIndexPath indexPathForRow:selectedSymptomIndex inSection:keyIndexNumber];
[selectedSympIPArray addObject:selectedSymptIndexPath];
}

In your code , you alloc every time in iteration. It's totally wrong. Find your mistake.
You can use this code....
selectedSympIPArray = [NSMutableArray array];
for (int i = 0 ; i<[notificationArray count]; i++)
{
selectedSymptIndexPath = [NSIndexPath indexPathForRow:selectedSymptomIndex inSection:keyIndexNumber];
[selectedSympIPArray addObject:selectedSymptIndexPath];
}

Related

how to take UITable view visible paths and more rows

Now I am taking index paths of visible tableview cells.But I want to take 3 more index path from visible rows,How can I do that ?
NSArray *visiblePaths = [tblView indexPathsForVisibleRows];
Assuming just one section, you can just create them, minding the max rows for that section:
NSMutableArray *visiblePaths = [tblView indexPathsForVisibleRows] mutableCopy];
NSInteger lastIndexPath = [visiblePaths lastObject];
NSInteger lastRow = lastIndexPath.row;
NSInteger extraRows = 3;
NSInteger maxRow = MIN(lastRow+extraRows, [self tableView:tblView numberOfRowsInSection:0] - 1);
for (int i = lastRow+1; i < maxRow; i++) {
NSIndexPath *newPath = [NSIndexPath indexPathForRow:i inSection:0];
[visiblePaths addObject:newPath];
}
It's doable for more sections (and/or for rows before the first visible) also. Hopefully it's clear how one would extend this to cover those requirements.

Populating UITableView cells

Ok so I have wrote some code in this function:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"tableviwcell is getting called");
properties = [NSUserDefaults standardUserDefaults];
NSDictionary *events_dict = [properties objectForKey:#"events_dict"];
NSDictionary *events = [events_dict objectForKey:#"event"];
am_participants = [events objectForKey:#"amParticipants"];
pm_participants = [events objectForKey:#"pmParticipants"];
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"currentCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"currentCell"];
}
int sizeofam = [am_participants count];
int sizeofpm = [pm_participants count];
NSMutableArray *participants =[[NSMutableArray alloc] init];
NSLog(#"size of am: %i", sizeofam);
if(sizeofam > 0 && sizeofpm > 0){
for(int i = 0; i < sizeofam; i++){
NSDictionary *ampart_dict = [am_participants objectAtIndex:i];
NSString *ampart_email = [ampart_dict objectForKey:#"email"];
NSString *ampart_email_extra = [#"am" stringByAppendingString:ampart_email];
[participants addObject:ampart_dict];
}
for(int i = 0; i < sizeofpm; i++){
NSDictionary *pmpart_dict = [pm_participants objectAtIndex:i];
NSString *pmpart_email = [pmpart_dict objectForKey:#"email"];
NSString *pmpart_email_extra = [#"pm" stringByAppendingString:pmpart_email];
[participants addObject:pmpart_dict];
NSLog(#"%#", participants);
}
int sizeofparticipants = [participants count];
for(int i = 0; i < sizeofparticipants; i++){
NSString *participanti = [[participants objectAtIndex:i] objectForKey:#"email"];
for(int j = 0; j < sizeofparticipants; j++){
NSString *participantj = [[participants objectAtIndex:j] objectForKey:#"email"];
if([participanti isEqualToString:participantj]){
NSLog(#"Participant j: %#", participantj);
[participants removeObjectAtIndex:j];
sizeofparticipants = [participants count];
}
}
}
Basically I need to merge together the two arrays am_participants and pm_participants in to one array of participants. Each object in the array is a dictionary full of various values such as name, email etc. I then have to remove any duplicate values from the list (for example if someone is in the am list and pm list. I am doing that by removing values if their email address is the same in either list.
After this I need to display the new array of participants called 'participants' in one list by populating the cells with the list of participants.
I have set the number of cells to 30.
However The cells get populated with different names randomly when scrolling down the list as thought the array positions are being moved around aswell as duplicate values appearing.
Can someone explain what I am doing wrong?
Thanks!
the cell assignment code is not mentioned above but i assume that you are assigning values from participants as your cell's content as explained. The problem is you are creating your array inside cellForRowAtIndexPath:. This method gets called every time a new cell is to be displayed, thus, you are recreating your participants for every row. You need to move the code you have above to viewDidLoad or viewDidAppear.

Error when trying to shuffle an NSMutableArray

I'm trying to shuffle an NSMutableArray so that its order will be mixed up every-time someone loads the view.
In my -(void)viewDidLoad I'm putting the following code (as suggested by other users):
NSMutableArray *shuffleTwo = [self.chosenTeamDict objectForKey:#"clubs"];
int random = arc4random() % [shuffleTwo count];
for (int i = 0; i < [shuffleTwo count]; i++) {
[shuffleTwo exchangeObjectAtIndex:random withObjectAtIndex:i];
}
NSLog(#"%#", shuffleTwo);
But when I do this and try and run the page, I get the following error:
2012-07-09 18:42:16.126 Kit-Quiz[6505:907] (null)
libc++abi.dylib: terminate called throwing an exception
Can anyone advice either a new way of shuffling this array, or advice me on how to avoid this error..!? I'm building for iOS 5 and I'm using Xcode45-DP1. Thanks in advance!
(EDIT)
I've also tried this method and I get the same error:
NSMutableArray *shuffledArray = [[NSMutableArray alloc] init];
NSMutableArray *standardArray = [self.chosenTeamDict objectForKey:#"clubs"];
for(int s = 0; s < [standardArray count]; s++){
int random = arc4random() % s;
[shuffledArray addObject:[standardArray objectAtIndex:random]];
}
NSLog(#"%#", shuffledArray);
NSMutableArray *standardArray = [self.chosenTeamDict objectForKey:#"clubs"];
int length = 10; // int length = [yourArray count];
NSMutableArray *indexes = [[NSMutableArray alloc] initWithCapacity:length];
for (int i=0; i<10; i++) [indexes addObject:[shuffledArray objectAtIndex:i]];
NSMutableArray *shuffle = [[NSMutableArray alloc] initWithCapacity:length];
while ([indexes count])
{
int index = rand()%[indexes count];
[shuffle addObject:[indexes objectAtIndex:index]];
[indexes removeObjectAtIndex:index];
}
for (int i=0; i<[shuffle count]; i++) NSLog(#"%#", [shuffle objectAtIndex:i]);
NSLog(#"%#", shuffle);
^^ ANSWER
Try Fisher-Yates shuffle. It goes like this:
int count = shuffledArray.count;
for(int i=count; i>0; i--) {
int j = arc4random_uniform(count);
[shuffledArray exchangeObjectAtIndex:j withObjectAtIndex:i];
}
make sure that your array is non-nil and all the entries are allocated objects :)
Source: Fisher-Yates Shuffle
First, you really should enable exception breakpoints. In XCode on the left-hand panel, click the breakpoint tab, click the "+" sign at the bottom-left -> exception breakpoint -> done.
I suspect your problem lies here:
int random = arc4random() % [shuffleTwo count];
If [shuffleTwo count] evaluates to zero (also if shuffleTwo is nil) it will throw a division by zero exception. Edit: Doesn't seem to be the case in Objective-C.

Loading values into an array from two different arrays iphone sdk

Here I am having a situation, I'm using the following code:
int x=0;
for (int i=0; i<=[arrayDeals count]-1; i++) {
x++;
//NSString *deal = [arrayDeals objectAtIndex:i];
combinedArr = [[NSMutableArray alloc]initWithObjects:
[CustomObject customObjectWithName:[arrayDeals objectAtIndex:i] andNumber:x],nil];
}
I need to load the values from arrayDeals and the 'x' value into combinedArr. So, I put this in a for loop. But i got only one value from each arrays. What is went wrong here? Please help me. (here CustomObject is a NSObject)
Thank you.
Well there are many things wrong with the code you posted, but I think this is what you want:
int x = 0;
NSMutableArray *combinedArr = [[NSMutableArray alloc] init]:
NSInteger count = [arrayDeals count];
for (int i = 0; i < count; i++) {
x++;
CustomObject *customObject = [CustomObject customObjectWithName:[arrayDeals objectAtIndex:i] andNumber:x];
[combinedArr addObject:customObject];
}
To give you some idea of what is wrong with the code you posted:
combinedArr = [[NSMutableArray alloc]initWithObjects:
[CustomObject customObjectWithName:[arrayDeals objectAtIndex:i] andNumber:x],nil];
Here you create a new NSMutableArray to which you assign an new object to taked the object from the array arrayDeals. But you create this NSMutableArray for every item in the array arrayDeals and you assign them to the same variable.
So each iteration you leak the NSMutableArray.
Also :
for (int i=0; i<=[arrayDeals count]-1; i++) {
is the same as
for (int i=0; i < [arrayDeals count]; i++) {
but the count is called every time you iterate, so as per my example I saved the count in a int to just speed things up.
You could even speed the code up using fast Enumeration:
NSInteger x = 0;
NSMutableArray *combinedArr = [[NSMutableArray alloc] init]:
for (id object in arrayDeals) {
id secondObject = [secondArray itemAtIndex:x];
// Arrays start at 0 so only up it after we've got the object.
x++;
CustomObject *customObject = [CustomObject customObjectWithName:object andNumber:x];
[combinedArr addObject:customObject];
}

Deleting multiple (not yet loaded) rows in UITableView

I'm having a bit of trouble trying to delete rows that haven't been loaded (or not visible) from a UITableview.
My setup is as follows -
There are two sections in the tableview and each element in section 1 is associated with multiple elements from section two.
To give you an example (The data isn't really related to what I'm trying to do, but I believe this will be an example that doesn't really require much explanation)
Section 1
BMW
Acura
Merc
Section 2
328i
335i
RX
LX
TX
C300
C550
My internal model goes something like this -
NSMutableArray Cars[]
NSMutableArray Models[]
cars[0] = "BMW"
cars[1] = "Acura"
cars[2] = "Merc"
Each element in Models[] is a vector and their conents are listed below
Models = [ ["328i", "335i"], ["RX", "LX", "TX"], ["C300", "C550"] ];
So for the functionality I'm trying to build. If the user clicks delete and tries to delete BMW, the App needs to remove the entry for BMW from section 1 and the entries for 328i and 335i in section two. However, the user is free to delete any single row of section two independently.
Can anyone point me to a way I can proceed with this?
NSMutableArray *Cars = [[NSMutableArray alloc] initWithObjects:#"BMW",#"Acura",#"Merc",nil];
NSMutableArray *Arr1 = [[NSMutableArray alloc]initWithObjects:#"328i", #"335i",nil];
NSMutableArray *Arr2 = [[NSMutableArray alloc]initWithObjects:#"RX", #"LX", #"TX",nil];
NSMutableArray *Arr3 = [[NSMutableArray alloc]initWithObjects:#"C300", #"C550",nil];
NSMutableArray * Models = [[NSMutableArray alloc] initWithObjects:Arr1,Arr2,Arr3,nil];
On delete if you delete BMW then remove 1st element from Models array and and 1st element from Cars array and reload table.
i.e.
[Cars removeObjectAtIndex:0];
[Models removeObjectAtIndex:0];
[tableview reload]; //tableview - object of UiTableView
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
int row = indexPath.row;
if(indexPath.section ==0) {
// Need to remove both the Car and the Models associated with it.
// Begin updates. Doesn't commit edits till endUpdates;
[tableView beginUpdates];
// Get the indexPaths to be removed.
// Cars is straight forward.
NSMutableArray *carsIndexPath = [[NSMutableArray alloc] init];
NSIndexPath *carsIndexPathObj = [NSIndexPath indexPathForRow:indexPath.row inSection:0];
[carsIndexPath addObject:carsIndexPathObj];
// Manually make index paths for models associated with the car.
NSMutableArray *modelIndexPaths = [self getIndexPaths:indexPath.row];
// Now remove from model
[models removeObjectAtIndex:indexPath.row];
[cars removeObjectAtIndex:indexPath.row];
// Remove from Table
[tableView deleteRowsAtIndexPaths:carsIndexPaths withRowAnimation:UITableViewRowAnimationLeft];
[tableView deleteRowsAtIndexPaths:modelIndexPaths withRowAnimation:UITableViewRowAnimationLeft];
// Commit updates
[tableView endUpdates];
// Reload data.
[tableView reloadData];
}
}
-(NSMutableArray *) getIndexPaths:(NSInteger) index {
NSMutableArray *indexPathArray = [[NSMutableArray alloc] init];
int offset = 0;
for (int i=0; i<index; i++) {
NSMutableArray *tempArr = [models objectAtIndex:i];
offset += [tempArr count];
}
NSMutableArray *currentModels = [models objectAtIndex:index];
for (int i=0; i<[currentModels count]; i++) {
NSIndexPath *indexPathTemp = [NSIndexPath indexPathForRow:offset+i inSection:1];
[indexPathArray addObject:indexPathTemp];
}
return indexPathArray;
}
(If this makes any sense at all)