Exception "mutating method sent to immutable object" - ios

I Had an exception in the line [array removeObjectsInArray:toRemove]; in the method below and can't understand what's wrong with it..
- (void) handleDearchForTerm:(NSString *)searchTerm
{
NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init];
[self resetSearch];
for (NSString *key in _keys)
{
NSMutableArray *array = [_names valueForKey:key];
NSMutableArray *toRemove = [[NSMutableArray alloc] init];
for (NSString *name in array)
{
if ([name rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location == NSNotFound)
[toRemove addObject:name];
}
if ([array count] == [toRemove count])
[sectionsToRemove addObject:key];
[array removeObjectsInArray:toRemove];
}
[_keys removeObjectsInArray:sectionsToRemove];
[_table reloadData];
}

Probably array is just instance of NSArray, but not NSMutableArray, you shall check _names setObject:forKeys:

Change:
NSMutableArray *array = [_names valueForKey:key];
To:
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:[_names valueForKey:key]];
Or:
NSMutableArray *array = [[_names valueForKey:key] mutableCopy];

Related

Split a single NSMutableArray into two so that I can set each in each of the section in UITableView

I want to use multiple sections feature UITableView. I have a single NSMutableArray which consists of data in dictionary format. In that dictionary there is a key which has values as '0' and '1'.
I want to create two separate NSMutableArray out of that so that I can assign them accordingly in different sections.
For example :
if (indexPath.section==0) {
NSDictionary *Data = [roomList1 objectAtIndex:indexPath.row];
} else {
NSDictionary *Data = [roomList2 objectAtIndex:indexPath.row];
}
Assuming the value in your dictionary is always set you could do something like:
NSMutableArray *firstArray = [NSMutableArray new];
NSMutableArray *secondArray = [NSMutableArray new];
for (NSDictionary *dictionary in yourArray) {
if ([dictionary objectForKey:#"yourValue"] isEqualToString: #"0") {
[firstArray addObject:dictionary];
} else if ([dictionary objectForKey:#"yourValue"]isEqualToString: #"1") {
[secondArray addObject:dictionary];
}
}
You can use this
- (NSDictionary *)groupObjectsInArray:(NSArray *)array byKey:(id <NSCopying> (^)(id item))keyForItemBlock
{
NSMutableDictionary *groupedItems = [NSMutableDictionary new];
for (id item in array) {
id <NSCopying> key = keyForItemBlock(item);
NSParameterAssert(key);
NSMutableArray *arrayForKey = groupedItems[key];
if (arrayForKey == nil) {
arrayForKey = [NSMutableArray new];
groupedItems[key] = arrayForKey;
}
[arrayForKey addObject:item];
}
return groupedItems;
}
Ref: Split NSArray into sub-arrays based on NSDictionary key values
Use like this
NSMutableArray * roomList1 = [[NSMutableArray alloc] init];
NSMutableArray * roomList2 = [[NSMutableArray alloc] init];
for(int i = 0;i< YourWholeArray.count;i++)
{
if([[[YourWholeArray objectAtIndex:i] valueForKey:#"YourKeyValueFor0or1"] isEqualToString "0"])
{
[roomList1 addObject:[YourWholeArray objectAtIndex:i]];
}
else if([[YourWholeArray objectAtIndex:i] valueForKey:#"YourKeyValueFor0or1"] isEqualToString "1"])
{
[roomList2 addObject:[YourWholeArray objectAtIndex:i]];
}
}
NSMutableArray *roomList1 = [[NSMutableArray alloc] init];
NSMutableArray *roomList2 = [[NSMutableArray alloc] init];
for (NSString *key in [myDictionary allKeys]) {
if (myDictionary[key] isEqualToString: #"0") {
[roomList1 addObject: myDictionary[key]];
} else {
[roomList2 addObject: myDictionary[key]];
}
}
try this way :-
NSMutableArray *getdata=[[NSMutableArray alloc]init];
getdata=[results objectForKey:#"0"];
NSMutableArray *getdata2=[[NSMutableArray alloc]init];
getdata2=[results objectForKey:#"1"];
use this two array and populate the section with now of rows at indexpathrow
define number of section 2
if (section==0){
getdata
}
else{
getdata2
}

iOS - How to get first charater of string from NSMutableArray and store it in NSMutableDictionary?

- (void)loadData: (NSMutableArray *)myMutableArray {
self.myMutableDict = [[NSMutableDictionary alloc] init];
for (NSString *str in myMutableArray) {
NSString *key = [str substringToIndex:1];
NSLog(#"Key: %#", key);
NSLog(#"str: %#", str);
if ([self.myMutableDict objectForKey:key]) {
NSMutableArray *list = (NSMutableArray *)[self.myMutableDict objectForKey:key];
[list addObject:str];
[self.myMutableDict setObject:list forKey:key];
} else {
NSMutableArray *list = [[NSMutableArray alloc] initWithObjects:str, nil];
[self.myMutableDict setObject:list forKey:key];
}
}
[self.tblAlphabeticalOrder reloadData];
}
Your mutable array has only one very long string with lots of commas in it. You need to quote each item separately:
NSArray *array = [[NSArray alloc] initWithObjects:#"Shyam", #"Ram", #"Hari", #"Gita", .....

Better way to convert NSArray of NSString to NSArray of NSNumber

Is there is a better way to convert NSArray of NSString into NSArray of NSNumber than the following code:
-(NSArray*) convertStringArrayToNumberArray:(NSArray *)strings {
NSMutableArray *numbers = [[NSMutableArray alloc] initWithCapacity:strings.count];
for (NSString *string in strings) {
[numbers addObject:[NSNumber numberWithInteger:[string integerValue]]];
}
return numbers;
}
-(NSArray *)convertStringArrayToNumberArray:(NSArray *)strings {
return [strings valueForKeyPath:#"self.integerValue"];
}
I test
NSArray * array = #[#"1",#"2",#"3"];
NSArray *num = [self convertStringArrayToNumberArray:array];
And result

Horizontally and Vertically scrollable table view with data from json

I want to create a table view which is scrollable both horizontally and vertically. I can do this by taking values myself. But I want to take the values from json. I am using model class and my json values are like this:
[
{
"cid": 109,
"iid": 10653,
"yr": 1994,
"val": "15.4311527806175"
},
{
"cid": 109,
"iid": 7872,
"yr": 1999,
"val": "8.84575553637328"
},
{
"cid": 109,
"iid": 7872,
"yr": 1998,
"val": "6.18441582677751"
},
I want my first column to be fixed when scrolling horizontally and first row to be fixed when I scroll it vertically. First column should have iid. first row should have yr and data should have val.
I am using XCMltisortTableView, ASIHttpRequest and SBJson.
I am getting the header value and left column value. How can I get the data corresponding to the yr and iid in proper column?
My code for val in requestFinished method is as follows:
rightTableData = [NSMutableArray arrayWithCapacity:mainTableData.count];
NSMutableArray *right = [NSMutableArray arrayWithCapacity:mainTableData.count];
for (int i = 0; i < mainTableData.count; i++)
{
// Model *model = [mainTableData objectAtIndex:i];
NSMutableArray *array = [NSMutableArray arrayWithCapacity:mainTableData.count];
for (int j = 0; j < headData.count; j++)
{
Model *model = [mainTableData objectAtIndex:j];
if([headData isEqual: #"2000"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else if([headData isEqual: #"2001"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else if([headData isEqual: #"2002"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else if([headData isEqual: #"2003"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else if([headData isEqual: #"2004"])
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
else
{
[array addObject:[NSString stringWithFormat:#"%#", model.val]];
}
}
[right addObject:array];
}
[rightTableData addObject:right];
I'm totally new and would a appreciate any answers and any suggestions. Please do reply.
Thanks!
After trying for a long time I got the result using the code below:
-(void) requestFinished: (ASIHTTPRequest *) request
{
NSString *theJSON = [request responseString];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSMutableArray *jsonDictionary = [parser objectWithString:theJSON error:nil];
headData = [[NSMutableArray alloc] init];
NSMutableArray *head = [[NSMutableArray alloc] init];
leftTableData = [[NSMutableArray alloc] init];
NSMutableArray *left = [[NSMutableArray alloc] init];
rightTableData = [[NSMutableArray alloc]init];
for (NSMutableArray *dictionary in jsonDictionary)
{
Model *model = [[Model alloc]init];
model.cid = [[dictionary valueForKey:#"cid"]intValue];
model.iid = [[dictionary valueForKey:#"iid"]intValue];
model.yr = [[dictionary valueForKey:#"yr"]intValue];
model.val = [dictionary valueForKey:#"val"];
[mainTableData addObject:model];
[head addObject:[NSString stringWithFormat:#"%ld", model.yr]];
[left addObject:[NSString stringWithFormat:#"%ld", model.iid]];
}
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:head];
headData = [[orderedSet array] mutableCopy];
NSOrderedSet *orderedSet1 = [NSOrderedSet orderedSetWithArray:left];
NSMutableArray *arrLeft = [[orderedSet1 array] mutableCopy];
//remove duplicate enteries from header array
[leftTableData addObject:arrLeft];
NSMutableArray *right = [[NSMutableArray alloc]init];
for (int i = 0; i < arrLeft.count; i++)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int j = 0; j < headData.count; j++)
{
/* NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.iid == %ld", [[arrLeft objectAtIndex:i] intValue]];
NSArray *filteredArray = [mainTableData filteredArrayUsingPredicate:predicate];*/
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.iid == %ld AND SELF.yr == %ld", [[arrLeft objectAtIndex:i] intValue], [[headData objectAtIndex:j] intValue]];
NSArray *filteredArray = [mainTableData filteredArrayUsingPredicate:predicate];
if([filteredArray count]>0)
{
Model *model = [filteredArray objectAtIndex:0];
[array addObject:model.val];
}
}
[right addObject:array];
}
[rightTableData addObject:right];
}
Hope it helps others.

how to change order of NSMutable array in same way another mutable arrays get changed

I have three arrays. They are name, birthdates and remaining days like below:
name birthdate remaining
"Abhi Shah", "01/14", 300
"Akash Parikh", "12/09/1989", 264
"Anand Kapadiya", "12/01", 256
"Annabella Faith Perez", "03/02", 347
"Aysu Can", "04/14/1992", 25
"Chirag Pandya" "10/07/1987" 201
I want to rearrange the remaining days array into ascending order,
but at the same time name and birthdate should also get reordered in the same way.
See this example below:
name birthdate remaining
"Aysu Can", "04/14/1992", 25
"Chirag Pandya" "10/07/1987" 201
"etc..."
use NSMutableDictionary to store data to NSMutableArray
NSMutableArray *array=[[NSMutableArray alloc]init];
for (int i=0; i<totalRows; i++)
{
NSMutableDictionary *dic=[[NSMutableDictionary alloc]init];
[dic setValue:[array_1 objectAtIndex:i] forKey:#"names"];
[dic setValue:[array_2 objectAtIndex:i] forKey:#"birthdate "];
[dic setValue:[array_3 objectAtIndex:i] forKey:#"remanning"];
[array addObject:dic];
[dic release];
}
here after you arrange name array,use search option to use name not use index and
use NSPredicate search data in NSMutableArray
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"names matches[cd] %#", name];
NSArray *result = [array filteredArrayUsingPredicate:predicate];
NSMutableDictionary *dict = [[[result objectAtIndex:0] mutableCopy] autorelease];
NSLog(#"%#",dict);// result
self.arrayForRows = [[NSMutableArray alloc]init];
NSMutableArray *arrayForNames = [[NSMutableArray alloc]initWithObjects:#"Abhi Shah",#"Akash",#"Nagavendra",#"Ramana",#"Simhachalam", nil];
NSMutableArray *arrayForBirthDates = [[NSMutableArray alloc]initWithObjects:#"01/14/94",#"01/14",#"11/07/87",#"12/07/89",#"23/08/91", nil];
NSMutableArray *arrayForRemaining = [[NSMutableArray alloc]initWithObjects:#"200",#"320",#"32",#"450",#"14", nil];
for (int i=0; i<arrayForBirthDates.count; i++)
{
NSMutableDictionary *tempDicts = [[NSMutableDictionary alloc]init];
[tempDicts setObject:[arrayForNames objectAtIndex:i] forKey:#"names"];
[tempDicts setObject:[arrayForBirthDates objectAtIndex:i] forKey:#"birth"];
[tempDicts setObject:[NSNumber numberWithInt:[[arrayForRemaining objectAtIndex:i] intValue]] forKey:#"remaining"];
[self.arrayForRows addObject:tempDicts];
}
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"remaining" ascending:YES];
[self.arrayForRows sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
Use this in tableView listing
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.arrayForRows count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifer = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifer];
}
cell.textLabel.text = [[self.arrayForRows objectAtIndex:indexPath.row] valueForKey:#"names"];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
once try like this it'l help you,
NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
[dict setObject:#"rahul" forKey:#"name"];
[dict setObject:#"10" forKey:#"value"];
NSMutableDictionary *dict1=[[NSMutableDictionary alloc]init];
[dict1 setObject:#"ttt" forKey:#"name"];
[dict1 setObject:#"6" forKey:#"value"];
NSMutableArray *ar=[[NSMutableArray alloc]init];
[ar addObject:dict];
[ar addObject:dict1];
NSSortDescriptor *Sorter = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:NO];
[ar sortUsingDescriptors:[NSArray arrayWithObject:Sorter]];
NSLog(#"---%#",ar);
Put each row into a dictionary, and out those dictionaries into an array. Then sort your away using a predicate or sort block. If you want an array containing just the sorted names for example, you could use [ array valueForKeyPath:#"name" ]
Array looks like:
[
{ #"name" : ...,
#"birthdate" : ...birthdate...,
#"remaining" : ...days remaining... } ,
{...},
{...}
]
such as your MutableArray is a Dictionarys array , you can use sortUsingComparator
to sort the array
[array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
int a = [(NSNumber *)[(NSDictionary *)obj1 objectiveForKey: #"remanning"] intValue];
int b = [(NSNumber *)[(NSDictionary *)obj2 objectiveForKey: #"remanning"] intValue];
if (a < b) {
return NSOrderedAscending;
}
else if(a == b)
{
return NSOrderedSame;
}
return NSOrderedDescending;
}];
For example , I have a test :
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#(30),#(20),#(5),#(100), nil];
[array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
int a = [(NSNumber *)obj1 intValue];
int b = [(NSNumber *)obj2 intValue];
if (a < b) {
return NSOrderedAscending;
}
else if(a == b)
{
return NSOrderedSame;
}
return NSOrderedDescending;
}];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"%# , %d",obj,idx);
}];
then the output is :

Resources