How to check array is empty in iPhone - ios

I have one array of array.I want check my inner array is empty or not.and I am checking objects of array are empty string.
Here is my code :
NSMutableArray *newArray = [NSMutableArray array];
NSMutableArray *selectArray = [NSMutableArray array];
for (int i = 0; i < [newArray count]; i++)
{
NSArray *arr = [newArray objectAtIndex:i];
if ([arr count] > 0)
{
NSString *str = [arr objectAtIndex:0];
if (![str isEqualToString:#""])
{
[selectArray addObject:str];
}
}
}
my newArray is array of array.I want to add strings in selectArray which are not empty.but, only 0th index object is added in selectArray multiple times.
Please suggest me, where i am doing wrong.thanks

Thats because you are just getting the 0'th element of your newArray's elements, I mean this line
NSString *str = [arr objectAtIndex:0];
you should put another for in your code. Use this code instead of yours
NSMutableArray *newArray = [NSMutableArray array];
NSMutableArray *selectArray = [NSMutableArray array];
for (int i = 0; i < [newArray count]; i++){
NSArray *arr = [newArray objectAtIndex:i];
for (int j = 0; j < [arr count]; j++){
NSString *str = [arr objectAtIndex:j];
if (![str isEqualToString:#""]){
[selectArray addObject:str];
}
}
}

Use this code You not need to create any extra variable.
for (int i = 0; i < [newArray count]; i++)
{
for (int j = 0; j < [[newArray objectAtIndex:i] count]; j++)
{
if (![[[newArray objectAtIndex:i] objectAtIndex:j] isEqualToString:#""])
{
[selectArray addObject:str];
}
}
}

You can use following generic function to check any of the value or object is empty or null.
-(BOOL)isEmpty:(id)object{
return object == nil
|| [object isKindOfClass:[NSNull class]]
|| ([object respondsToSelector:#selector(length)]
&& [(NSData *)object length] == 0)
|| ([object respondsToSelector:#selector(count)]
&& [(NSArray *)object count] == 0);
}

You can try with this
NSMutableArray *newArray = [NSMutableArray array];
NSMutableArray *selectArray = [NSMutableArray array];
for (NSArray *arrayFromNewArray in newArray) {
if ([arrayFromNewArray count] > 0)
{
NSString *str = [arrayFromNewArray firstObject];
if (![str isEqualToString:#""])
{
[selectArray addObject:str];
}
}
}

You should be
NSMutableArray *newArray = [NSMutableArray array];
NSMutableArray *selectArray = [NSMutableArray array];
for (int i = 0; i < [newArray count]; i++)
{
NSArray *arr = [newArray objectAtIndex:i];
for (int j = 0; j < [arr count]; j++)
{
NSString *str = [arr objectAtIndex:j];
if (![str isEqualToString:#""])
{
[selectArray addObject:str];
}
}
}
Problem is you forgot the second loop :) Let me know if I am correct.

Related

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 can I sort a second array based on a first array which was sorted with NSPredicate?

I have two NSMutableArrays: searchResults and searchResultsDetails. I sort searchResults with NSPredicate, and I want searchResultsDetails to be sorted based on which objects were removed from searchResults with the NSPredicate.
For example, let's say searchResults originally contains 1,2,3,4,5 and searchResultsDetails originally contains A,B,C,D,E. So after sorting it with NSPredicate, searchResults contains 1,2,5, and I want searchResultsDetails to contain A,B,E. How can I accomplish this?
This is the code I am using to sort the first array.
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"self CONTAINS %#",
searchText];
self.searchResults = [self.lines filteredArrayUsingPredicate:resultPredicate];
NSMutableArray *firstArray = [[NSMutableArray alloc] initWithObjects:#"ashu",#"toremove",#"ashuabc",#"toremove",#"ashu12345", nil];
NSMutableArray *descriptionArray = [[NSMutableArray alloc] initWithObjects:#"description for ashu",#"description for non ashu",#"description for ashuabc",#"description for nopnashu",#"description for ashu12345", nil];
NSMutableArray *removedIndexArray = [[NSMutableArray alloc] init];
NSMutableArray *sortedArray = [[NSMutableArray alloc] init];
for (int i = 0; i < [firstArray count]; i++) {
NSString *tempStr = [firstArray objectAtIndex:i];
if ([tempStr rangeOfString:#"ashu"].location == NSNotFound) {
[removedIndexArray addObject:[NSString stringWithFormat:#"%d",i]];
} else {
[sortedArray addObject:tempStr];
}
}
for (int j = 0; j < [removedIndexArray count]; j++) {
[descriptionArray removeObjectAtIndex:[[removedIndexArray objectAtIndex:j] integerValue]];
}
NSLog(#"%#",descriptionArray);
NSLog(#"Sorted array is :: %#",sortedArray);

how to sort Chinese character into # in UILocalizedIndexedCollation

i'm wondering on how to sort Chinese character into "#" instead of A-Z.
any comments are greatly appreciated.
-(NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector
{
self.collation = [UILocalizedIndexedCollation currentCollation];
NSInteger sectionCount = [[self.collation sectionTitles] count];//section count is take from sectionTitles and not sectionIndexTitles
NSMutableArray *unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount];
//create an array to hold the data for each section
for(int i = 0; i < sectionCount; i++)
{
[unsortedSections addObject:[NSMutableArray array]];
}
//put each object into a section
for (id object in array)
{
NSInteger index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
//sort each section
for (NSMutableArray *section in unsortedSections)
{
[sections addObject:[self.collation sortedArrayFromArray:section collationStringSelector:selector]];
}
return sections;
}
This is what i ended up doing
-(NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector
{
self.collation = [UILocalizedIndexedCollation currentCollation];
NSInteger sectionCount = [[self.collation sectionTitles] count];//section count is take from sectionTitles and not sectionIndexTitles
NSMutableArray *unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount];
//create an array to hold the data for each section
for(int i = 0; i < sectionCount; i++)
{
[unsortedSections addObject:[NSMutableArray array]];
}
if ([self.catString isEqualToString:ARTISTS])
{
//put each object into a section
for (id object in array)
{
if (!object)
{
continue;
}
NSInteger index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
}
else
{
NSInteger index;
for (id object in array)
{
Song *songItem = object;
NSString* charIndex;
if([songItem.songName length]<=2)
{
charIndex = [songItem.songName substringToIndex:1];
}
else if([songItem.songName length]<=3)
{
charIndex = [songItem.songName substringToIndex:2];
}
else if([songItem.songName length]<=4)
{
charIndex = [songItem.songName substringToIndex:3];
}
else if([songItem.songName length]>=5)
{
charIndex = [songItem.songName substringToIndex:4];
}
NSRegularExpression *regex = [[NSRegularExpression alloc]
initWithPattern:#"[a-zA-Z]" options:0 error:NULL];
NSUInteger matches = [regex numberOfMatchesInString:charIndex options:0
range:NSMakeRange(0, [charIndex length])];
if (matches >=2)
{
index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
else
{
index = 26; //add object to last index "#"
[[unsortedSections objectAtIndex:index] addObject:object];
}
songItem = nil;
}
}
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
//sort each section
for (NSMutableArray *section in unsortedSections)
{
[sections addObject:[self.collation sortedArrayFromArray:section collationStringSelector:selector]];
}
return sections;
}

How to show an index that looks like the iPod music with # for non english songs

I would like to show an index bar on my tableview with all my songs sorted by alphabetical order and those foreign language songs and numerical in # just like how the iPod music in iOS.
I read the first character of all my song array object exclude duplicates and append it as the index.
How can i filter foreign / non alphabet and numbers ?
this is how it looks like, ugly.
would to show something like iPod.
-(NSMutableArray *)updateSongSectionIndexWithArray:(NSArray*)songArray andSelector:(SEL)selector
{
NSArray *indexedArray = [self partitionObjects:songArray collationStringSelector:selector];
return [[NSMutableArray alloc]initWithArray:indexedArray];
}
-(NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector
{
self.collation = [UILocalizedIndexedCollation currentCollation];
NSInteger sectionCount = [[self.collation sectionTitles] count];//section count is take from sectionTitles and not sectionIndexTitles
NSMutableArray *unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount];
//create an array to hold the data for each section
for(int i = 0; i < sectionCount; i++)
{
[unsortedSections addObject:[NSMutableArray array]];
}
if ([self.catString isEqualToString:ARTISTS])
{
//put each object into a section
for (id object in array)
{
if (!object)
{
continue;
}
NSInteger index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
}
else
{
for (id object in array)
{
NSInteger index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
}
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
//sort each section
for (NSMutableArray *section in unsortedSections)
{
[sections addObject:[self.collation sortedArrayFromArray:section collationStringSelector:selector]];
}
return sections;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] count];
}
I did a similar solution for a contacts application. I start by defining the alphabet myself, then you can add to each section the items that fit (case insensitive compare for the letters, Characterset for the numbers). After the list is filled, you can remove (or hide) the sections which have no entry.
I did a similar thing for one of my apps. To split titles I used this code:
NSString* alphabet = #"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
NSArray* indexes = [alphabet componentsSeparatedByString:#""];
for (NSString* title in self.titles) {
char c = [[title uppercaseString] characterAtIndex:0];
NSString* index = [NSString stringWithFormat:#"%c",c];
if ([alphabet rangeOfString:index].location == NSNotFound) {
//The title does not start with a valid letter
index = #"#";
}
NSMutableArray* sectionObjects = [self.sections objectForKey:index];
if (!sectionObjects) {
sectionObjects = [[NSMutableArray alloc] init];
[self.sections setObject:sectionObjects forKey:index];
}
[sectionObjects addObject:title];
}
Obviously this code is still missing the sort part since it's trivial.
I ended up getting this my index to work by this
-(NSArray *)partitionObjects:(NSArray *)array collationStringSelector:(SEL)selector
{
self.collation = [UILocalizedIndexedCollation currentCollation];
NSInteger sectionCount = [[self.collation sectionTitles] count];//section count is take from sectionTitles and not sectionIndexTitles
NSMutableArray *unsortedSections = [NSMutableArray arrayWithCapacity:sectionCount];
//create an array to hold the data for each section
for(int i = 0; i < sectionCount; i++)
{
[unsortedSections addObject:[NSMutableArray array]];
}
if ([self.catString isEqualToString:ARTISTS])
{
//put each object into a section
for (id object in array)
{
if (!object)
{
continue;
}
NSInteger index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
}
else
{
NSInteger index;
for (id object in array)
{
Song *songItem = object;
NSString* charIndex;
if([songItem.songName length]<=2)
{
charIndex = [songItem.songName substringToIndex:1];
}
else if([songItem.songName length]<=3)
{
charIndex = [songItem.songName substringToIndex:2];
}
else if([songItem.songName length]<=4)
{
charIndex = [songItem.songName substringToIndex:3];
}
else if([songItem.songName length]>=5)
{
charIndex = [songItem.songName substringToIndex:4];
}
NSRegularExpression *regex = [[NSRegularExpression alloc]
initWithPattern:#"[a-zA-Z]" options:0 error:NULL];
NSUInteger matches = [regex numberOfMatchesInString:charIndex options:0
range:NSMakeRange(0, [charIndex length])];
if (matches >=2)
{
NSLog(#"matches %i",matches);
index = [self.collation sectionForObject:object collationStringSelector:selector];
[[unsortedSections objectAtIndex:index] addObject:object];
}
else
{
index = 26;
[[unsortedSections objectAtIndex:index] addObject:object];
}
NSLog(#"songItem %# is in index %i",songItem.songName, index);
}
}
NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount];
//sort each section
for (NSMutableArray *section in unsortedSections)
{
[sections addObject:[self.collation sortedArrayFromArray:section collationStringSelector:selector]];
}
return sections;
}

UIPickerView cannot display JSON array data

This is my first time doing an iOS app, so I may not know some stuff that may seem easy. Please be patient with me =)
Basically, I need to fill up my UIPickerView with data from my JSON. I have successfully parsed my JSON data and pulled out what I need and placed them into an NSMutableArray. When I first tried to do the UIPickerView, I used hardcoded array, and everything was working fine. Now, when I try to replace the hardcoded array with my JSON array, I keep getting a null JSON array. The way it works, it seems that the UIPickerView tried to pull everything out before my JSON array is filled.
I have tried reloading the UIPickerView as suggested elsewhere on this site, and it also isn't working.
The following are parts of my code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
dispatch_async(randomiserBgQ, ^{
NSData* data = [NSData dataWithContentsOfURL:randomiserCatURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData{
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray* randomiserCat = [json objectForKey:#"categories"];
self.randCatSel =[[NSMutableArray alloc] init];
NSLog(#"categories: %#", randomiserCat);
for (int i = 0; i < [randomiserCat count]; i++) {
NSDictionary *dict = [randomiserCat objectAtIndex:i];
NSString* parent = [dict objectForKey:#"name"];
[self.randCatSel addObject:parent];
NSArray* childrenArray = [dict objectForKey:#"children"];
for (int i = 0; i < [childrenArray count]; i++) {
NSDictionary* dict = [childrenArray objectAtIndex:i];
NSString* children = [dict objectForKey:#"name"];
[self.randCatSel addObject:children];
NSArray* grandchildrenArray = [dict objectForKey:#"grandchildren"];
for (int i = 0; i < [grandchildrenArray count]; i++) {
NSDictionary* dict = [grandchildrenArray objectAtIndex:i];
NSString* grandchildren = [dict objectForKey:#"name"];
[self.randCatSel addObject:grandchildren];
}
}
}
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component
{
return [self.randCatSel count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [self.randCatSel objectAtIndex:row];
}
As you can see, the way I tried to parse my JSON data, I used such a long method as I have a few levels of arrays in the JSON data. If there is a faster method (like foreach in PHP), please point me in the right direction as well.
So far, my UIPickerView is getting a empty randCatSel array (I presume it is loading it before it is filled).
hi please try this,
- (void)fetchedData:(NSData *)responseData
{
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray* randomiserCat = [json objectForKey:#"categories"];
self.randCatSel =[[NSMutableArray alloc] init];
NSLog(#"categories: %#", randomiserCat);
for (int i = 0; i < [randomiserCat count]; i++) {
NSDictionary *dict = [randomiserCat objectAtIndex:i];
NSString* parent = [dict objectForKey:#"name"];
[self.randCatSel addObject:parent];
NSArray* childrenArray = [dict objectForKey:#"children"];
for (int i = 0; i < [childrenArray count]; i++) {
NSDictionary* dict = [childrenArray objectAtIndex:i];
NSString* children = [dict objectForKey:#"name"];
[self.randCatSel addObject:children];
NSArray* grandchildrenArray = [dict objectForKey:#"grandchildren"];
for (int i = 0; i < [grandchildrenArray count]; i++) {
NSDictionary* dict = [grandchildrenArray objectAtIndex:i];
NSString* grandchildren = [dict objectForKey:#"name"];
[self.randCatSel addObject:grandchildren];
}
}
}
packerView=[[UIPickerView alloc] initWithFrame:CGRectMake(0, 280, 320, 200)];
packerView.delegate=self;
packerView.dataSource=self;
[self.view addSubview:packerView];
}
//add the picker view delegate and datasource in .h file. and set the frame as per your requirement.
hope this will help you.
As pointed out by the wonderful people here, all I had to do was to reload the UIPickerView in my fetchedData method. I previously put it in viewDidLoad =/
[pickerViewObj reloadAllComponents];
Where pickerViewObj is your own UIPickerView.

Resources