NSMutableArray, checking which Value is the most abundant? - ios

How can I check which value in an NSMutableArray is the most frequent?
Array = "0,2,3,2,2,4
the value = "2".

Take a look at NSCountedSet this will help with your problem.
NSCountedSet *countedSet = [[NSCountedSet alloc] initWithArray:youArray];
NSInteger maxCount = 0;
id maxObject = nil;
for (id object in countedSet) {
if ([countedSet object] > maxCount) {
maxCount = [countedSet countForObject:object];
maxObject = object;
}
}
return maxObject;
This does sound like homework though.
EDIT
If they are stored as strings instead of numbers then swap out NSNumber for NSString everything else works the same.
EDIT
Actually, I just realised that it doesn't care about what object type it is...
Latest edit will work whatever the object is.

Related

I need to have a mutable Array that has 8 interpolated strings in IOS

I'm new to IOS and I'm not sure if I'm on the right track. What I need to know is if I'm on the right track and if I'm off it a hint on what to fix so I can get back on track. The mutable Array should read an array of speakers and say "Hello, my name is <speakerArray>" it should do that 8 times with a different name each time. This is what I Have:
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
for(speakers i = 0; i => 7; i++)
{
NSString *greetings =#"Hello, my name is .";
NSMutableArray *badges = [speakers arrayByAddingObjectsFromArray:greetings];
}
return badges;
}
Let's take this one step at a time. First of all, your operator in the loop is wrong; you mean to execute while i is less than or equal to 7. Thus, change => to <=. However, it's more stylish to say i < 8. And finally, it's most stylish of all to use what's called "Fast Enumeration", which allows you to loop without an index at all. In fact, it will work no matter how many items are in your speakers array! That takes us here:
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
for (NSString* speaker in speakers)
{
NSString *greetings =#"Hello, my name is .";
NSMutableArray *badges = [speakers arrayByAddingObjectsFromArray:greetings];
}
return badges;
}
Next, greetings isn't an array! It's a string. That's why calling -arrayByAddingObjectsFromArray: doesn't make any sense, and why the compiler isn't going to like it. Let's make its name singular, greeting, to reflect this fact. Strategy: Your goal here is to create an empty array, then construct items one by one and add them to that array. That takes us to:
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
NSMutableArray *badges = [NSMutableArray array]; //Here we make an empty array
for (NSString* speaker in speakers)
{
NSString *greeting =#"Hello, my name is .";
[badges addObject:greeting]; //Here we add one item to it each time 'round the loop
}
return badges;
}
Last, your string has no interpolation right now! It reads literally "Hello, my name is ." We do string interpolation using the -stringWithFormat: method.
Finished Product:
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
NSMutableArray *badges = [NSMutableArray array];
for (NSString* speaker in speakers)
{
NSString *greeting = [NSString stringWithFormat:#"Hello, my name is %#.",speaker];
[badges addObject:greeting];
}
return badges;
}
That should get you started with fast enumeration and string interpolation. Remember to compile your code often and try to understand the compiler errors--it would have helped you with some of these issues.
Maybe you mean this
- (NSMutableArray *)badgesForSpeakers:(NSArray *)speakers {
NSMutableArray *badges = [[NSMutableArray alloc] init];
for (NSString *speaker in speakers) {
[badges addObject:[NSString stringWithFormat:#"Hello, my name is %#", speaker]];
}
return badges;
}
plz use this code
- (NSArray*)badgesForSpeakers:(NSArray*)speakers {
NSMutableArray *badges = [NSMutableArray alloc];
for(int i = 0; i < speakers.count; i++)
{
NSString *greetings =[NSString stringWithFormat:#"Hello, my name is .%#",[speakers objectAtIndex:i]];
badges = [speakers addObject:greetings];
}
return [badges copy];
}

Creating Different Permutations from different Arrays Values

I am trying to write a method which allows me to create a different String permutations, based on the values I have stored within 3 different arrays. Currently I have a NSMutableDictionary that contains 3 different keys, and associated to each key we have an NSMutableArray array that contains a list of different String objects.
How woulld I loop through each of my NSMutableArray arrays which are stored within my NSMutableDictionary, and build a string value for each node from the arrays. So essentially, something like the following: A1[0] = "Hello", A2[0] = "There", A3[0] = "Guys", which would essentially build me a string like this: "HelloThereGuys".
Any suggestions, or possibly different approaches to this problem will be appreciated.
First of all I want to agree with hochl. ;-) But I think, that you want to create a string containing a word from each array in the same index position?
NSMutableArray *enums = [NSMutableArray new];
for( NSString *key in dictionary )
{
NSEnumerator *enum = [dictionary[key] objectEnumerator]; // Forgot that in prior version
[enums addObject:enum];
}
while( YES )
{
NSMutableString *line = [NSMutableString new];
BOOL done = NO;
for( NSEnumerator *enum in enums )
{
NString *word = [enum nextObject];
if( word == nil )
{
done = YES;
break;
}
[line addString:word];
}
if (done)
{
break;
}
NSLog (#"%#", line );
}
Did I get you right?

Previous NSDictionary now to JSON array

- (void)retrieveData
{
NSURL * url = [NSURL URLWithString:#"***/connection.php"];
NSData * data = [NSData dataWithContentsOfURL:url];
_json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
_questionsArray = [[NSMutableArray alloc]init];
for (int i = 0; i < _json.count; i++)
{
NSString * qID = [[_json objectAtIndex:i] objectForKey:#"id"];
NSString * qTitle = [[_json objectAtIndex:i] objectForKey:#"question_title"];
NSString * qA = [[_json objectAtIndex:i] objectForKey:#"A"];
NSString * qB = [[_json objectAtIndex:i] objectForKey:#"B"];
NSString * qC = [[_json objectAtIndex:i] objectForKey:#"C"];
NSString * qD = [[_json objectAtIndex:i] objectForKey:#"D"];
NSString * qAnswer = [[_json objectAtIndex:i] objectForKey:#"question_answer"];
question * myQuestion = [[question alloc] initWithQuestionID:qID andQuestionName:qTitle andQuestionA:qA andQuestionB:qB andQuestionC:qC andQuestionD:qD andQuestionAnswer:qAnswer];
[_questionsArray addObject:myQuestion];
}
[_json enumerateObjectsUsingBlock:^(NSDictionary *questionDictionary, NSUInteger idx, BOOL *stop) {
//Here I'm treating the index like an NSNumber, if your code is expecting a string instead use
//#(idx).stringValue
[_questions setObject:questionDictionary forKey:#(idx)];
//or the modern equivalent
//questions[#(idx)] = questionDictionary;
//If you want to use your 'questions class' then create one and put it into the array instead of the dictionary pulled from the array.
}];
NSLog( #"%#", _questions );
}
Logs (null)
random gobledy gook so my post isn't mostly code
random gobledy gook so my post isn't mostly code
random gobledy gook so my post isn't mostly code
random gobledy gook so my post isn't mostly code
random gobledy gook so my post isn't mostly code
If I understand your question correctly it becomes something like this
self.questions = .... //I assume this is the array you reference 'question' objects that is created by your retrieve data method
//this used to be created by pulling an object out of your questions dictionary with the key i interpreted as a string.
//now that it's an array you should be able to just reference it by index, assuming they were inserted in order
//I'm also assuming that what comes out of the aray is a question object given the code you provided with the signature
//- (id) initWithQuestionID: (NSString *) qID andQuestionName: (NSString *) qName andQuestionA: (NSString *) qA andQuestionB: (NSString *) qB andQuestionC: (NSString *) qC andQuestionD: (NSString *) qD andQuestionAnswer: (NSString *) qAnswer
Question *nextQuestion = self.questions[i];
self.answer = nextQuestion.questionAnswer;
self.questionLabel.text = nextQuestion.questionLabel;
//and so on
I also suggest the following edit to replace your for loop. It uses a for in loop instead, this saves you from having to keep track of an index and looks cleaner. It also helps so you don't keep repeating the [_json objectAtIndex:i] chunk of code. I also use modern objective-c syntax to access the dictionary.
for (NSDictionary *questionDictionary in _json)
{
NSString * qID = questionDictionary[#"id"];
NSString * qTitle = questionDictionary[#"question_title"];
...
question * myQuestion = [[question alloc] initWithQuestionID:qID andQuestionName:qTitle andQuestionA:qA andQuestionB:qB andQuestionC:qC andQuestionD:qD andQuestionAnswer:qAnswer];
[_questionsArray addObject:myQuestion];
}
If you need the key along with the object in the dictionary then you can clean it up in a similar way with the enumerateObjectsUsingBlock
[_json enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
//your code here
}];
EDIT
It sounds like what your really wanting to do is to pull down your JSON but keep all your other code the way it was when you were using a dictionary that you got from your plist. So in this case you want your parsing function to return a dictionary instead of an array. If that's the case it's worth sidestepping into computer science for a second.
NSDictionarys are also known as a hash, map, symbol table, or associative array. Some languages (such as Lua) don't have an array collection like NSArray, they only have dictionaries. From a dictionary you can create many of the other collections your used to like arrays (and sets too). Heres how it works: Instead of an ordered collection of elements with an index, you place the items in a dictionary and use what would have been the index as the key, and the value becomes, well, the value. For example an array and it's equivalent associative array (aka dictionary):
NSArray *array = #[#"hello", #"world", #"!"];
NSDictionary *dictionary = #{#(1): #"hello",
#(2): #"world",
#(3): #"!"};
This is exactly what your doing when you load in the data from your plist because the first elements key is 0 followed by another dictionary, and I'm supposing that the next element in the list is 1 followed by another dictionary. Inside your parsing function it becomes
NSMutableDictionary *questions = [[NSMutableDictionary alloc] init];
[_json enumerateObjectsUsingBlock:^(NSDictionary *questionDictionary, NSUInteger idx, BOOL *stop) {
//Here I'm treating the index like an NSNumber, if your code is expecting a string instead use
//#(idx).stringValue
[questions setObject:questionDictionary forKey:#(idx)];
//or the modern equivalent
//questions[#(idx)] = questionDictionary;
//If you want to use your 'questions class' then create one and put it into the array instead of the dictionary pulled from the array.
}];
This of course assumes that your api is going to return the JSON questions in the order you want.

Loading NSMutableArray objects into an IBCollection of Labels

My problem is that when I use fast enumeration to load objects from my array, like so:
for(SetOfObjects *set in _myArray){
NSLog (#"%#"[set anObject];
}
It will print out my specified object without a problem, however when it comes time to assign these objects to an NSArray of labels. The last object returns as 0.
Like so:
for(SetOfObjects *set in _myArray){
for(UILabel *label in _arrayOfLabels){
int i = [set intObject];
NSString *string = [NSString stringWithFormat:#"%i",i];
label.text = string;
}
}
I think, I have gone wrong here. The code works, but the problem is that all labels are then set as 0.
Any tips welcome.
You are iterating the labels within each SetOfObjects instance, when in fact you want to iterate both arrays at the same time, which cannot be done using fast enumeration.
Instead revert to indexed-access of both arrays:
NSInteger count = [_myArray count];
NSAssert([_arrayOfLabels count] == count, #"Different array sizes!");
for (NSInteger index = 0; index < count; index++) {
SetOfObjects *set = _myArray[index];
UILabel *label = _arrayOfLabels[index];
int i = [set intObject];
NSString *string = [NSString stringWithFormat:#"%i",i];
label.text = string;
}
Note the assertion to check that both arrays are the same size.
EDIT: Oops, i was a bad variable name to choose for the index...

ios sort a mutable dictionary order [duplicate]

This question already has answers here:
NSDictionary with ordered keys
(9 answers)
Closed 8 years ago.
I saw many examples on SO but I'm not sure if it applies to this situation. Everywhere it says NSMutableDictionries are not guaranteed an order...but I'm getting my data from the server...so my NSMuteDic looks like this:
{
joe = (
{
fromName = joe;
id = 25;
theMessage = "this is going to be a really big message...";
timeAdded = "2014-04-07 21:08:12";
toName = "me";
},
{
fromName = joe;
id = 10;
theMessage = "why???";
timeAdded = "2014-04-05 20:10:04";
toName = "me";
}
);
bob = (
{
fromName = "me";
id = 24;
theMessage = "blah blah";
timeAdded = "2014-04-06 21:15:06";
toName = bob;
},
{
fromName = bob;
id = 22;
theMessage = message;
timeAdded = "2014-04-06 20:11:57";
toName = "me";
}
);
//more entries here
}
What I want to do is change the order...put bob first and joe second. Is this really impossible to do? I saw many very complex solutions...there's no easy way to do this with just a for loop?
cellForRowAtIndexPath:
NSMutableArray *temp = [myDict objectForKey:keys[indexPath.row]];
cell.Message.text = [[reverse lastObject] valueForKey:#"theMessage"];
cell.dateTime.text = [[reverse lastObject] valueForKey:#"timeAdded"];
return cell;
This is how I'm using it...and when a row is selected I pass the array to the next view controller. The reason why I want to reorder is if a new message will be inserted in the pushed view controller, I want that dictionary to be first in the list so the root view controller can be reordered.
NSArray *keys = [myDict allKeys];
[myDict removeObjectForKey:to];
NSMutableDictionary *temp = [NSMutableDictionary dictionaryWithCapacity:[myDict.count];
temp = myDict;
[myDict removeAllObjects];
[myDict setObject:currentDict forKey:to];
for (int i=0; i<temp.count; i++) {
[myDict setObject:[temp valueForKey:keys[i]] forKey:keys[i]];
}
That's not working because it looks like since myDict is a NSObject, temp gets changed every time myDict changes...from the looks of it the logic should work but it isn't...
NSMutableDictionary is not ordered. There is nothing you can do to guarantee the order of keys because NSDictionary makes no attempt to preserve any particular ordering. To go over a dictionary in a particular order, you have to make an array of the keys that is in the order you want, then iterate that and fetch the corresponding values.
// Get the keys
NSArray *keys = [myDict allKeys];
// Sort the keys
NSArray *sortedArray = [NSArray arrayWithArray:[keys sortedArrayUsingComparator:^(NSString* a, NSString* b) {
return [a compare:b];
}]];
// Iterate the dictionary
for (NSUInteger n = 0 ; < [sortedArray count]; n++) {
id value = [myDict objectForKey:[sortedArray objectAtIndex:n]];
}

Resources