I am working on SQLite and I have written a query which returns me two arrays ItemsArray and CustomersIDArray as:
ItemsArray
Element at Index 0 = Off White,
Element at Index 1 = Fan,
Element at Index 2 = Off White,
Element at Index 3 = Delux,
Element at Index 4 = Fan
CustomerIDArray
Element at Index 0 = 1,
Element at Index 1 = 2,
Element at Index 2 = 2,
Element at Index 3 = 3,
Element at Index 4 = 4
I want result like that Off White = 2 (count) , Fan = 2 (count) and Delux = 1;
and the Resultant Array,
Result Array
Element at Index 0 = Off White,
Element at Index 1 = Fan,
Element at Index 2 = Delux
Actually I want the count of repetition in first array but the value must not same for CustomerArray.
Please help me through logic or code.
-(NSMutableArray *)getCountAndRemoveMultiples:(NSMutableArray *)array{
NSMutableArray *newArray = [[NSMutableArray alloc]initWithArray:(NSArray *)array];
NSMutableArray *countArray = [NSMutableArray new];
int countInt = 1;
for (int i = 0; i < newArray.count; ++i) {
NSString *string = [newArray objectAtIndex:i];
for (int j = i+1; j < newArray.count; ++j) {
if ([string isEqualToString:[newArray objectAtIndex:j]]) {
[newArray removeObjectAtIndex:j];
countInt++;
}
}
[countArray addObject:[NSNumber numberWithInt:countInt]];
countInt = 1;
}
NSMutableArray *finalArray = [[NSMutableArray alloc] initWithObjects:newArray, countArray, nil];
NSLog(#"%#", finalArray);
return finalArray;
}
- (IBAction)getArrayInfo:(id)sender {
NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:#"Off White", #"Fan", #"Off White", #"Deluxe", #"Fan", nil];
NSMutableArray *godArray = [self getCountAndRemoveMultiples:myArray];
NSLog(#"Array from this end = %#", godArray);
}
I just set up -getArrayInfo to test it out. Works fine. As you can see, the array you want to display will be at index:0, and the countArray at index:1.
Use NSCountedSet like below
NSMutableArray *ary_res = [[NSMutableArray alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"11",#"13",#"34",#"9",#"13",#"34",#"9",#"2",nil];
NSCountedSet *set = [[NSCountedSet alloc] initWithArray:array];
for(id name in set)
{
if([set countForObject:name]==2)
[ary_res addObject:name];
}
//
NSLog(#"%#",ary_res);
try this:
NSArray *copy = [ItemsArray copy];
NSInteger index = [copy count] - 1;
for (id object in [copy reverseObjectEnumerator]) {
if ([ItemsArray indexOfObject:object inRange:NSMakeRange(0, index)] != NSNotFound) {
[ItemsArray removeObjectAtIndex:index];
}
index--;
}
Related
I have the array like:
(
{
id=1;
Title="AAAA";
period_id=1;
},
{
id=2;
Title="BBBB";
period_id=2;
},
{
id=3;
Title="CCCC";
period_id=2;
},
{
id=4;
Title="DDDD";
period_id=2;
},
{
id=5;
Title="EEEE";
period_id=3;
},
)
Question: How can i know that Period_id=2 is multiple times in the array?
Help me solve this.
Thank you,
There are lots of ways to do so, Some of them are here ..
A:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"period_id == %#", #"2"];
NSArray *newArray = [array filteredArrayUsingPredicate:predicate];
NSLog(#"%d", [newArray count]);
B:
NSMutableArray *newArray = [[NSMutableArray alloc] init];
for (id obj in array)
{
if([obj[#"period_id"] isEqualToString:#"2"]){
[newArray addObject:obj];
}
}
NSLog(#"%d", [newArray count]);
C:
NSArray *allIds = [array valueForKey:#"period_id"];
NSCountedSet *set = [[NSCountedSet alloc] initWithArray:allIds];
for (id item in set)
{
NSLog(#"period_id=%#, Count=%d", item,[set countForObject:item]);
}
D:
NSArray *allIds = [array valueForKey:#"period_id"];
__block NSMutableArray *newArray = [[NSMutableArray alloc] init];
NSString *valueToCheck = #"2";
[allIds enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if([obj isEqualToString:valueToCheck])
[newArray addObject:obj];
}];
NSLog(#"%d", [newArray count]);
E:
NSIndexSet *indexes = [array indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
return [[obj objectForKey:#"period_id"] isEqualToString:#"2"];
}];
NSArray *newArray = [array objectsAtIndexes:indexes];
NSLog(#"%d", [newArray count]);
try like this,
NSIndexSet *indices = [questionSections indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
return [[obj objectForKey:#"period_id"] isEqualToString:#"2"];
}];
NSArray *filtered = [questionSections objectsAtIndexes:indices];
NSLog(#"duplictae:%d\n %#",[indices count],filtered);
O/P:-
duplicate: 3
(
{
name = bbbb;
"period_id" = 2;
},
{
name = ccccc;
"period_id" = 2;
},
{
name = ddddd;
"period_id" = 2;
}
)
if the array is sorted, as it seems at your case, just check if the next item has the same value as this one
for(int i = 0; i < array.size() - 1; i++) {
if (array[i].id == array[i + 1].id) {
// Duplicate
}
}
if you just want to know about id = 2
int idCount = 0;
for(int i = 0; i < array.size() - 1; i++) {
if (array[i].id == 2) {
idCount++;
}
}
if you also want to know the location
int idCount = 0;
int idarr[array.size()];
for(int i = 0; i < array.size() - 1; i++) {
if (array[i].id == 2) {
idarr[idCount++] = i;
}
}
I think this is a JSON response from what I gather. Yes you can get the period_id. Add all the period_id's in an NSMutableArray.
Then simply search for the period_id from within this array for the values of the period_id to be same . You will get the index on which the period_id's are same.
NSSet *uniqueElements = [NSSet setWithArray:myArray];
for(id element in uniqueElements) {
// iterate here
}
You could also use NSPredicate to check duplicate.
Try this Example:
NSPredicate *testPredicate = [NSPredicate predicateWithFormat:#"period_id.intValue == %d",value];
NSMutableArray *data = [[NSMutableArray alloc] init];
NSArray *testArray= [yourArray filteredArrayUsingPredicate:testPredicate];
NSLog(#"duplicate:%d",[testArray count]);
I have a NSDictionary that contains objects and keys. The Keys hold a Name and number. I would like to insert those objects into a NSMutableArray by using insertObject: atIndex: . Object being the name and the number is the index I would like to place the object in. I now know that NSMutableArrays are able to insert objects at index:6 if there is no 1-5 so how do I make this possible? Any suggestions are very appreciated!
Example Dictionary [dict objectForKey:#"array"]:
preferences as whole (
{
Name = PowerDown;
btnIndex = 3;
},
{
Name = ClearCache;
btnIndex = 5;
},
{
Name = KillBGApps;
btnIndex = 6;
},
{
Name = InfoPanel;
btnIndex = 2;
},
{
Name = Lock;
btnIndex = 4;
},
{
Name = Reboot;
btnIndex = 0;
},
{
Name = Respring;
btnIndex = 1;
}
)
What I have so far but crashes when adding objects out of bounds of the array
-(void)loadArray{
self.buttons = [NSMutableArray array];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
tempArray = [buttonsPrefs objectForKey:#"buttonsToOrder"];
for(NSDictionary * dict in tempArray)
{
if (dict) {
NSString *btnName = [dict objectForKey:#"Name"];
NSString *btnIndex = [dict objectForKey:#"btnIndex"];
NSUInteger index = [btnIndex integerValue];
NSLog(#"Name = %#",btnName);
NSLog(#"at index %i",index);
[self.buttons insertObject: btnName atIndex: index];
}
}
}
EDIT: These values "indexes" for the names with change when a user moves the cell
- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath
*)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
NSUInteger fromIndex = [fromIndexPath row];
NSUInteger toIndex = [toIndexPath row];
if (fromIndex == toIndex)
return;
NSMutableDictionary *selectedButton = [[[_buttons objectAtIndex:fromIndex] retain]
autorelease];
[_buttons removeObjectAtIndex:fromIndex];
[_buttons insertObject:selectedButton atIndex:toIndex];
//[buttonsPrefs setObject:_buttons forKey:#"buttonsToOrder"];
//[buttonsPrefs writeToFile:[self getFilePath] atomically: YES];
}
Try to fill your target array with some dummy data according to yourDict count like this:
for (int i=0, i<[yourDict count], ++i){
[yourArray addObject:#"dummyData"];
}
And when you will need to insertObject do this:
for(NSDictionary * dict in tempArray)
{
if (dict) {
NSString *btnName = [dict objectForKey:#"Name"];
NSString *btnIndex = [dict objectForKey:#"btnIndex"];
NSUInteger index = [btnIndex integerValue];
[yourArray insertObject:btnName atIndex:index];
[yourArray removeObjectAtIndex:index+1];
}
}
NSMutableArray insertObject: atIndex:
as per apple docs `
"Note that NSArray objects are not like C arrays. That is, even though
you specify a size when you create an array, the specified size is
regarded as a “hint”; the actual size of the array is still 0. This
means that you cannot insert an object at an index greater than the
current count of an array."
Can only fill within valid array value set.Two things you can do.
Sort and fill the array
Fill the array with some default object like a string(cannot be nil) and then replace it.This option is valid if you are filling all the values in array because when used later you have to check weather the value is right there or the default value is in that position
I currently have this method:
-(void)seperateGuides
{
DLog("GetGuideListCount: %i", [[appDelegate getGuideList] count]);
columnOneArray = [[NSMutableArray alloc] init];
columnTwoArray = [[NSMutableArray alloc] init];
columnThreeArray = [[NSMutableArray alloc] init];
for (int i = 0; i < [[appDelegate getGuideList] count]; i = i + 3) {
[columnOneArray addObject:[[appDelegate getGuideList]objectAtIndex:i]];
}
for (int i = 1; i < [[appDelegate getGuideList] count]; i = i + 3) {
[columnTwoArray addObject:[[appDelegate getGuideList]objectAtIndex:i]];
}
for (int i = 2; i < [[appDelegate getGuideList] count]; i = i + 3) {
[columnThreeArray addObject:[[appDelegate getGuideList]objectAtIndex:i]];
}
}
And need to do this more dynamic, so I can define how many arrays I want and then get the arrays.
Different possibilities I'm considering is making it a mutli-dimensional array (although I'm not sure how to handle it in Objectvie-C), or making a method that simply loops through as many times as I define, the problem there is that I'm not quite sure how to get the different arrays.
A simple algorithm or another possible solution would be greatly appreciated.
The algorithm you're describing sounds equivalent to what we do when we deal a deck of cards into multiple hands, so I'd do it like this:
- (NSArray *)dealObjects:(NSArray *)objects intoArrays:(NSInteger)numArrays
{
NSMutableArray *arrays = [NSMutableArray arrayWithCapacity:numArrays];
for (a = 0; a < numArrays; a++) {
[arrays addObject:[NSMutableArray arrayWithCapacity:[objects count] / numArrays];
}
for (i = 0; i < [objects count]; i++) {
[[arrays objectAtIndex:i % numArrays] addObject:[objects objectAtIndex:i]];
}
return arrays;
}
You can add multiple array to another arrays as this,
-(void)seperateGuides:(int)columnCount
{
rootArray=[[NSMutableArray alloc] init];
for(int i=0;i<columnCount;i++)
{
column = [[NSMutableArray alloc] init];
for(int j=i;j<[[appDelegate getGuideList] count];j=j+3)
{
[column addObject:[[appDelegate getGuideList]objectAtIndex:j]];
[rootArray addObject:column];
[column release];
}
}
}
Quite simple really. Just add new NSArray objects to a root array as you iterate through your dataset.
- (void)seperateGuides {
DLog("GetGuideListCount: %i", [[AppDelegate getGuideList] count]);
NSArray *root = [[NSArray alloc] init];
int dimensions = anyIntGreaterThanZero;
for (int i = 0; i < dimensions; i += dimensions) {
NSArray *branch = [[NSArray alloc] init];
int k = 0;
for (k += i; k < [[AppDelegate getGuideList] count]; k += dimensions) {
[branch addObject:[[AppDelegate getGuideList] objectAtIndex:k]];
}
[root arrayByAddingObject:branch];
}
}
-(void)seperateGuides
{
NSMutableArray *parentArray = [[NSMutableArray alloc]init];
int count = [[appDelegate getGuideList] count];
int TOTAL_COLUMNS = 3;//Define number of columns here
for (int i = 0; i <count; i++)
{
int columnNo = i % TOTAL_COLUMNS;
if(parentArray.count > columnNo)
{
NSMutableArray *innerArray = [parentArray objectAtIndex:columnNo];
[innerArray addObject:[[appDelegate getGuideList]objectAtIndex:i]];
}
else
{
NSMutableArray *innerArray = [NSMutableArray arrayWithObject:[[appDelegate getGuideList]objectAtIndex:i]];
[parentArray insertObject:innerArray atIndex:columnNo];
}
}
}
Hope this helps...
Here parentArray will have NSMutableArray as its members. Each array represents the objects in a column.
I have model class which contains NSString's- studentName, studentRank and studentImage. I wanna sort the NSMutableArray according to studentRanks. what I have done is
- (void)uploadFinished:(ASIHTTPRequest *)theRequest
{
NSString *response = nil;
response = [formDataRequest responseString];
NSError *jsonError = nil;
SBJsonParser *json = [[SBJsonParser new] autorelease];
NSArray *arrResponse = (NSArray *)[json objectWithString:response error:&jsonError];
if ([jsonError code]==0) {
// get the array of "results" from the feed and cast to NSArray
NSMutableArray *localObjects = [[[NSMutableArray alloc] init] autorelease];
// loop over all the results objects and print their names
int ndx;
for (ndx = 0; ndx < arrResponse.count; ndx++)
{
[localObjects addObject:(NSDictionary *)[arrResponse objectAtIndex:ndx]];
}
for (int x=0; x<[localObjects count]; x++)
{
TopStudents *object = [[[TopStudents alloc] initWithjsonResultDictionary:[localObjects objectAtIndex:x]] autorelease];
[localObjects replaceObjectAtIndex:x withObject:object];
}
topStudentsArray = [[NSMutableArray alloc] initWithArray:localObjects];
}
}
How can I sort this topStudentsArray according to the ranks scored by the Students and If the two or more student have the same rank, How can I group them.
I did like this
TopStudents *object;
NSSortDescriptor * sortByRank = [[[NSSortDescriptor alloc] initWithKey:#"studentRank" ascending:NO] autorelease];
NSArray * descriptors = [NSArray arrayWithObject:sortByRank];
NSArray * sorted = [topStudentsArray sortedArrayUsingDescriptors:descriptors];
but this is not displaying results properly. please help me to overcome this problem. thanks in advance.
doing something like this might do the trick
Initially sort the arrGroupedStudents in the (ascending/descending) order of studentRank
//Create an array to hold groups
NSMutableArray* arrGroupedStudents = [[NSMutableArray alloc] initWithCapacity:[topStudentsArray count]];
for (int i = 0; i < [topStudentsArray count]; i++)
{
//Grab first student
TopStudents* firstStudent = [topStudentsArray objectAtIndex:i];
//Create an array and add first student in this array
NSMutableArray* currentGroupArray = [[[NSMutableArray alloc] initWithCapacity:0] autorelease];
[currentGroupArray addObject:firstStudent];
//create a Flag and set to NO
BOOL flag = NO;
for (int j = i+1; j < [topStudentsArray count]; j++)
{
//Grab next student
TopStudents* nextStudent = [topStudentsArray objectAtIndex:j];
//Compare the ranks
if ([firstStudent.studentRank intValue] == [nextStudent.studentRank intValue])
{
//if they match add this to same group
[currentGroupArray addObject:nextStudent];
}
else {
//we have got our group so stop next iterations
[arrGroupedStudents addObject:currentGroupArray];
// We will assign j-1 to i
i=j-1;
flag = YES;
break;
}
}
//if entire array has students with same rank we need to add it to grouped array in the end
if (!flag) {
[arrGroupedStudents addObject:currentGroupArray];
}
}
Finally your arrGroupedStudents will contain grouped array with equal rank. I have not test run the code so you might need to fix a few things falling out of place. Hope it helps
If you want to display in the order of ranks, you should set the ascending as YES.
NSSortDescriptor * sortByRank = [[NSSortDescriptor alloc] initWithKey:#"studentRank" ascending:YES];
static int mySortFunc(NSDictionary *dico1, NSDictionary *dico2, void *context)
{
NSString *studentName1 = [dico1 objectForKey:#"studentName"];
NSString *studentName2 = [dico2 objectForKey:#"studentName"];
return [studentName1 compare:studentName2];
}
- (IBAction)sortBtnTouched:(id)sender
{
[topStudentsArray sortUsingFunction:mySortFunc context:NULL];
}
I have a table view, which has its data source from an array that contains names of people.
Now to make it easy to find people, I want to section the table view so that it has the letter A-Z on the right hand side, just like the Address Book app.
But my current array just contains a collection of NSStrings. How do I split them so that they are grouped by the first letter of the names? Is there any convenient way to do it?
EDIT: If anyone's interested in my final code:
NSMutableArray *arrayChars = [[NSMutableArray alloc] init];
for (char i = 'A'; i <= 'Z' ; i++) {
NSMutableDictionary *characterDict = [[NSMutableDictionary alloc]init];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
for (int k = 0; k < [myList count]; k++) {
NSString *currentName = [[friends objectAtIndex:k] objectForKey:#"name"];
char heading = [currentName characterAtIndex:0];
heading = toupper(heading);
if (heading == i) {
[tempArray addObject:[friends objectAtIndex:k]];
}
}
[characterDict setObject:tempArray forKey:#"rowValues"];
[characterDict setObject:[NSString stringWithFormat:#"%c",i] forKey:#"headerTitle"];
[arrayChars addObject:characterDict];
[characterDict release];
[tempArray release];
}
At the end of the function I'll have:
arrayChars [0] = dictionary(headerTitle = 'A', rowValues = {"adam", "alice", etc})
arrayChars[1] = dictionary(headerTitle = 'B', rowValues = {"Bob", etc})
Thank you everyone for your help!
You can use a dictionary to sort them, so create an array with all the letters you want to sort and a array with nil objects to initialize the dictionary
NSArray *names = #[#"javier",#"juan", #"pedro", #"juan", #"diego"];
NSArray *letters = #[#"j", #"p", #"d"];
NSMutableArray *objects = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < [letters count]; ++i)
{
[objects addObject:[[NSMutableArray alloc] init]];
}
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:letters];
Then you must find the first letter if the word and put that word into the corresponding key in the dictionary
for (NSString *name in names) {
NSString *firstLetter = [name substringToIndex:1];
for (NSString *letter in letters) {
if ([firstLetter isEqualToString:letter]) {
NSMutableArray *currentObjects = [dictionary objectForKey:letter];
[currentObjects addObject:name];
}
}
}
To check you can print directly the dictionary
NSLog(#"%#", dictionary);
Then is your work to fill your sections in the tableview using the dictionary