count occurrences in a NSArray - ios

this is a part of my code from a NSArray:
2012-06-03 16:03:45.140 test[4178:f803] data (
{
receiver = david;
sender = james;
idMessage = 248;
},
{
receiver = david;
sender = james;
idMessage = 247;
},
{
receiver = david;
sender = Marc;
idMessage = 246;
}
)
I want the number of messages sent by sender to receiver or something like that
james = 2;
marc = 1;

"data" is the NSArray, which appears to contain NSDictionary objects.
So you'd want to loop through the array this way:
NSNumber * countOfSender;
NSString * nameOfSender;
NSMutableDictionary * countDictionary = [[NSMutableDictionary alloc] initWithCapacity: 1];
// go through the original array to examine each sender
for(NSDictionary *anEntry in data)
{
nameOfSender = [anEntry objectForKey: #"sender"];
if(sender)
{
countOfSender = [countDictionary objectForKey: nameOfSender];
if(countOfSender == NULL)
{
// create a new count entry for this particular sender
countOfSender = [NSNumber numberWithInt: 1];
} else {
// increment the previous count
countOfSender = [NSNumber numberWithInt: [countOfSender intValue] + 1];
}
[countDictionary setObject: countOfSender forKey: nameOfSender];
}
}
// now print out the outputs
for(nameOfSender in [countDictionary allKeys])
{
countOfSender = [countDictionary objectForKey: nameOfSender];
NSLog( #"%# : %d" nameOfSender, [countOfSender intValue] );
}

You would do something like..
NSMutableArray *array = [NSMutableArray array];
for(id object in yourArray) {
NSLog("sender:%# id:%i",[object valueForKey:#"sender"],[[object valueForKey:#"idMessage"] intValue]);
NSMutableDictionary *dict = [
NSMutableDictionary dictionary];
[dict setValue:[object valueForKey:#"sender"] forKey:#"sender"];
[dict setValue:[NSNumber numberWithInt:[[object valueForKey:#"idMessage"] intValue]] forKey:#"idMessage"];
[array addObject:dict];
}
NSLog(#"%#",array);

Related

How to form an JSON formatted Mutable Array in Objective C

I need to form a JSON Formatted Mutable Array based on the response, initially I get ID from DB from that DB I need to Check in an Empty array then Add Elements to the array with respect to Key values, when its runs for next time The Array contains ID so I have to append the KEY and Values to the Respective Id
Here my Sample Code:
if ([hashTableArr1 containsObject:assignItmId]) {
// [testDict setObject:assignItmId forKey:#"id"];
[testDict2 setObject:keyname forKey:#"keyname"];
[testDict2 setObject:value forKey:#"value"];
[hashTableArr addObject:testDict2];
[testDict setObject:hashTableArr forKey:#"result"];
[hashTableArr1 addObject:testDict];
}
else{
NSMutableDictionary *dict1 = [[NSMutableDictionary alloc]init];
NSMutableArray *arr1 = [[NSMutableArray alloc]init];
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc]init];
[dict2 setObject:assignItmId forKey:#"id"];
[dict1 setObject:keyname forKey:#"keyname"];
[dict1 setObject:value forKey:#"value"];
[arr1 addObject:dict1];
[dict2 setObject:arr1 forKey:#"result"];
[hashTableArr1 addObject:dict2];
}
My output is:
(
{
id = "1";
result = (
{
keyname = "Date";
value = "06-02-2017";
}
);
},
{
id = "1";
result = (
{
keyname = Vendor;
value = "";
}
);
},
{
id = "1";
result = (
{
keyname = Owner;
value = XXX;
}
);
},
Expected Results :
(
{
id = "1";
result = (
{
keyname = "Purchase Date";
value = "06-02-2017";
},
{
keyname = Vendor;
value = "";
},
{
keyname = Owner;
value = XXX;
}
);
}
Please Update the suitable solution
What you are doing now is you are adding an array in result key every time and then dictionary into your main array but for your expected result you have to maintain an array outside the loop and add the object into your array which you maintain outside the loop and after this add this array in result key of a dictionary and then add this dictionary into main array.
You have to put this code outside from your loop
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc]init];
[dict2 setObject:assignItmId forKey:#"id"];
NSMutableArray *arr1 = [[NSMutableArray alloc]init];
In Loop
if ([hashTableArr1 containsObject:assignItmId]) {
// [testDict setObject:assignItmId forKey:#"id"];
[testDict2 setObject:keyname forKey:#"keyname"];
[testDict2 setObject:value forKey:#"value"];
[arr1 addObject:testDict2];
}
else{
NSMutableDictionary *dict1 = [[NSMutableDictionary alloc]init];
[dict1 setObject:keyname forKey:#"keyname"];
[dict1 setObject:value forKey:#"value"];
[arr1 addObject:dict1];
}
After loop
[dict2 setObject:arr1 forKey:#"result"];
[hashTableArr1 addObject:dict2];

Max value for each object in an Array of Dictionaries

I have an array of dictionaries that I am trying to get the Max score for each player in the array. Each player can have multiple entries I am trying to get an array of dictionaries of each players best score.
NSArray
[0] - NSDictionary
- [0] Score: (double)20.7
- [1] NameID: (int) 1
- [2] Date
[1] - NSDictionary
- [0] Score: (double)25
- [1] NameID: (int) 1
- [2] Date
[2] - NSDictionary
- [0] Score: (double)28
- [1] NameID: (int) 2
- [2] Date
[3] - NSDictionary`
- [0] Score: (double)26
- [1] NameID: (int) 3
- [2] Date
I have tried using NSPredicate predicateWithFormat but I am only able to get back the max for everything in the array not related to the name.
Expected Output:
NSArray
[1] - NSDictionary
- [0] Score: (double)25
- [1] NameID: (int) 1
- [2] Date
[2] - NSDictionary
- [0] Score: (double)28
- [1] NameID: (int) 2
- [2] Date
[3] - NSDictionary`
- [0] Score: (double)26
- [1] NameID: (int) 3
- [2] Date
Thanks for the help.
You can't use an NSPredicate for this, since you want to determine the maximum score for several different players. Under the covers, NSPredicate iterates the array anyway, so using your own loop isn't any less efficient. In the following code I have assumed that the scores and player names are wrapped in NSNumber
-(NSArray *)maxScoresForPlayers:(NSArray *)playerScores {
NSMutableDictionary *maxScores = [NSMutableDictionary new];
for (NSDictionary *player in playerScores) {
NSNumber *playerID = (NSNumber *)player[#"NameID"];
NSDictionary *playerMax = maxScores[playerID];
if (playerMax == nil) {
playerMax = player;
} else {
NSNumber *currentMax = (NSNumber *)[playerMax[#"Score"];
NSNumber *playerScore = (NSNumber *)player[#"Score"];
if ([playerScore doubleValue] > [currentMax doubleValue]) {
playerMax = player;
}
}
maxScores[playerID] = playerMax;
}
return([maxScores allValues];
}
You can do it manually like this:
NSMutableDictionary *maxScoresDict = [NSMutableDictionary dictionary];
for (NSDictionary *score in scoresArray) {
NSNumber *key = score[#"NameID"];
NSNumber *savedMax = maxScoresDict[key][#"Score"];
NSNumber *currentMax = maxScoresDict[key][#"Score"];
if (savedMax == nil || [currentMax doubleValue] > [savedMax doubleValue]) {
maxScoresDict[key] = score;
}
}
NSArray *maxScoresArray = [maxScoresDict allValues];
Try this:
NSArray *objects = #[#{#"Score": #(20.7),
#"NameID": #(1),
#"Date": [NSDate date]},
#{#"Score": #(25),
#"NameID": #(1),
#"Date": [NSDate date]},
#{#"Score": #(28),
#"NameID": #(2),
#"Date": [NSDate date]},
#{#"Score": #(26),
#"NameID": #(3),
#"Date": [NSDate date]}];
NSMutableArray *users = [NSMutableArray array];
for (NSInteger i=0; i<objects.count; i++) {
NSDictionary *dict = objects[i];
NSNumber *nameID = dict[#"NameID"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.NameID==%#", nameID];
NSInteger index = [users indexOfObjectPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
BOOL found = [predicate evaluateWithObject:obj];
return found;
}];
if (index != NSNotFound) {
NSNumber *score1 = dict[#"Score"];
NSNumber *score2 = users[index][#"Score"];
if (score1.doubleValue > score2.doubleValue) {
[users replaceObjectAtIndex:index withObject:dict];
}
}
else {
[users addObject:dict];
}
}
NSLog(#"%#", users);
- (NSArray *)getBestScores:(NSArray *)players {
NSMutableDictionary *best = [[NSMutableDictionary alloc] init];
for (NSDictionary *p in players) {
NSDictionary *b = [best valueForKey:[p valueForKey:#"NameID"]];
if (!b || [[p valueForKey:#"Score"] doubleValue] > [[b valueForKey:#"Score"] doubleValue])
[best setValue:p forKey:[p valueForKey:#"NameID"]];
}
return [best allValues];
}
// Get Max Value of integer element from Array of Dictonaries.
// Example Array Starts
<paramArray>(
{
DicID = 1;
Name = "ABC";
ValuetoCalculateMax = 2800;
},
{
DicID = 2;
Name = "DEF";
ValuetoCalculateMax = 2801;
},
{
DicID = 3;
Name = "GHI";
ValuetoCalculateMax = 2805;
}
)
// Example Array Ends
// Implementation
int MaxintegerValue=0;
MaxintegerValue=[self getMaxValueFromArrayofDictonaries:paramArray];
// Implementation Ends
// Function Starts
-(int)getMaxValueFromArrayofDictonaries:(NSArray *)paramArray
{
int MaxValue=0;
NSMutableDictionary *dic=[[NSMutableDictionary alloc]init];
for ( int i=0; i<[paramArray count]; i++ )
{
dic=[paramArray objectAtIndex:i];
if ([[dic valueForKey:#"ValuetoCalculateMax"] intValue] > MaxValue)
{
MaxValue=[[dic valueForKey:#"ValuetoCalculateMax"] intValue];
}
else
{
MaxValue=MaxValue;
}
}
return MaxValue;
}
// Function Ends
What you need to do is find scores for each user, then find the max score out of it.
- (void)findMaxScoreForUser:(int)userId {
NSDictionary *dict0 = [NSDictionary dictionaryWithObjects:#[#27.0,#3] forKeys:#[#"Score",#"UserID"]];
NSDictionary *dict1 = [NSDictionary dictionaryWithObjects:#[#25.0,#2] forKeys:#[#"Score",#"UserID"]];
NSDictionary *dict2 = [NSDictionary dictionaryWithObjects:#[#23.0,#3] forKeys:#[#"Score",#"UserID"]];
NSArray *arr = [NSArray arrayWithObjects:dict0,dict1,dict2, nil];
NSMutableArray *scores = [NSMutableArray array];
for (NSDictionary *dict in arr) {
int userID = [[dict valueForKey:#"UserID"] intValue];
if (userId == userID) {
[scores addObject:[dict valueForKey:#"Score"]];
}
}
int max = [[scores valueForKeyPath:#"#max.intValue"] intValue];
}

IOS: how to join 2 Dictionaries into 1 dictionary??

in my project i applied the following code
NSDictionary *dict6 = [self cleanJsonToObject:responseData];
NSLog(#"str : %#",dict6);
diagnosisdict = [[[dict6 objectForKey:#"diagnoses"] objectAtIndex:0] objectForKey:#"DiagnosesHospitals"];
diagnosedictforname = [[[dict6 objectForKey:#"diagnoses"]objectAtIndex:0]objectForKey:#"Diagnoses"];
NSLog(#" for ref id =%# ,name of diagnose=%# data is= %#",refidstr,diagnosedictforname ,diagnosisdict);
and the output in console is comes out as in the form
str : {
diagnoses = (
{
Diagnoses = {
"diagnosis_name" = "TRANSIENT ISCHEMIA";
};
DiagnosesHospitals = {
"charge_amt" = "1300.00";
discharges = "11200.00";
"hospital_id" = 3341;
id = 163080;
"medicare_amt" = "100.00";
"total_amt" = "1100.00";
};
}
);
response = 200;
}
ref id =3341 ,name of diagnose={
"diagnosis_name" = "TRANSIENT ISCHEMIA";
} data is= {
"charge_amt" = "1300.00";
discharges = "11200.00";
"hospital_id" = 3341;
id = 163080;
"medicare_amt" = "100.00";
"total_amt" = "1100.00";
}
now i just want to embed the values of both the Dictionaries into one dictionary
someone please help me to sort out this issue.
Make a mutable copy of the first dictionary:
NSMutableDictionary * mutDic = [dic1 mutableCopy];
and then:
[mutDic addEntriesFromDictionary:dic2];
Try this code:
NSDictionary *dict6 = [self cleanJsonToObject:responseData];
NSLog(#"str : %#",dict6);
NSMutableDictionary *diagnosisdict = [[[dict6 objectForKey:#"diagnoses"] objectAtIndex:0] objectForKey:#"DiagnosesHospitals"];
NSDictionary *diagnosedictforname = [[[dict6 objectForKey:#"diagnoses"]objectAtIndex:0]objectForKey:#"Diagnoses"];
NSArray *keys = [diagnosedictforname allKeys];
for (int i =0; i < keys.count; i++) {
NSString *key = [keys objectAtIndex:i];
[diagnosisdict setValue:[diagnosedictforname valueForKey:key] forKey:key];
}
NSLog(#"your dic -> %#", diagnosisdict);

Convert NSString into NSDIctionary

I have a string ------ NSString abc = #"apple:87,banana:32,grapes:54";
i need this output like this
{
name = "apple";
value = "87";
},
{
name = "banana";
value = "32";
},
{
name = "grapes";
value = "54";
}
I have tried:
NSArray* itemList = [abc componentsSeparatedByString:#","];
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
for (NSString* item in itemList) {
NSArray* subItemList = [item componentsSeparatedByString:#":"];
if (subItemList.count > 0) {
[dict setObject:[subItemList objectAtIndex:1] forKey:[subItemList objectAtIndex:0]];
}
}
NSLog(#"%#", dict);
The output is --
{
apple = 87;
banana = 32;
grapes = 54;
}
but i dont want this output
The wanted output is a NSArray of NSDictionary.
So:
NSArray* itemList = [abc componentsSeparatedByString:#","];
NSMutableArray *finalArray = [[NSMutableArray alloc] init];
for (NSString *aString in itemList)
{
NSArray* subItem = [aString componentsSeparatedByString:#":"];
NSDictionary *dict = #{#"name":[subItem objectAtIndex:0],
#"value":[subItem objectAtIndex:1]};
[finalArray addObject:dict];
}
I didn't use the if ([subItem count] > 0), trying just to keep the logic you missed and clarify the algorithm.
I didn't test the code, but that should do it. (or maybe a little compiler error easy to correct).
In case anyone wants the equivalent in Swift:
let abc = "apple:87,banana:32,grapes:54"
let dict = abc.componentsSeparatedByString(",").map { pair -> [String: String] in
let parts = pair.componentsSeparatedByString(":")
return ["name": parts[0], "value": parts[1]]
}

how to update NSMutableArray data depending on id or based on position

I have NSMutableArray data as below.
(
{
Id = 3;
Name = Fahim;
},
{
Id = 2;
Name = milad;
},
{
Id = 1;
Name = Test;
}
)
Now I want to update the name from Test to Omar (for id = 1).
Any idea how to get this done?
Answer
With below answer, I was getting error as -[__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance. To resolve that issue I Changed [feeds addObject:[item copy]] to [feeds addObject:item]
for (NSMutableDictionary* aDict in yourMutableArray) {
if (aDict[#"id"] == 1) {
[aDict setObject:#"Omar" forKey:#"Name"];
}
}
EDIT :
NSMutableArray* mutableArray = [[NSMutableArray alloc]init];
NSDictionary* item1Dict = [NSDictionary dictionaryWithObjectsAndKeys:
#"1",#"id",
#"Fahim",#"name"
, nil];
NSMutableDictionary* item1 = [NSMutableDictionary dictionaryWithDictionary:item1Dict];
[mutableArray addObject:item1];
NSDictionary* item2Dict = [NSDictionary dictionaryWithObjectsAndKeys:
#"2",#"id",
#"milad",#"name"
, nil];
NSMutableDictionary* item2 = [NSMutableDictionary dictionaryWithDictionary:item2Dict];
[mutableArray addObject:item2];
NSDictionary* item3Dict = [NSDictionary dictionaryWithObjectsAndKeys:
#"3",#"id",
#"test",#"name"
, nil];
NSMutableDictionary* item3 = [NSMutableDictionary dictionaryWithDictionary:item3Dict];
[mutableArray addObject:item3];
NSLog(#"%#",mutableArray);
for (NSMutableDictionary* aDict in mutableArray) {
if ([aDict[#"id"] isEqualToString:#"3"]) {
[aDict setObject:#"Omar" forKey:#"name"];
}
}
NSLog(#"%#",mutableArray);
And for much elegant:
NSMutableArray* mutableArray = [[NSMutableArray alloc]init];
NSArray* name = [NSArray arrayWithObjects:#"Fahin",#"milad",#"test", nil];
for (int i = 0; i < name.count; i++) {
NSDictionary* itemd = [NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:#"%i",i],#"id",
name[i],#"name"
, nil];
NSMutableDictionary* item = [NSMutableDictionary dictionaryWithDictionary:itemd];
//or
//NSMutableDictionary* item = [item mutableCopy];
[mutableArray addObject:item];
}
NSLog(#"%#",mutableArray);
for (NSMutableDictionary* aDict in mutableArray) {
if ([aDict[#"id"] isEqualToString:#"2"]) {
[aDict setObject:#"Omar" forKey:#"name"];
}
}
NSLog(#"%#",mutableArray);
logs are:
2013-10-18 00:51:48.845 test[34919:60b] (
{
id = 1;
name = Fahim;
},
{
id = 2;
name = milad;
},
{
id = 3;
name = test;
}
)
second log:
2013-10-18 00:52:06.887 test[34919:60b] (
{
id = 1;
name = Fahim;
},
{
id = 2;
name = milad;
},
{
id = 3;
name = Omar;
}
)
EDIT2 for copy:
-copy, as implemented by mutable Cocoa classes, always returns their immutable counterparts. When an NSMutableDictionary is sent -copy, it returns an NSDictionary containing the same objects. NSMutableDictionary is a subclass of NSDictionary, the compiler doesn't complain. NSDictionary does not recognize it's mutable subclass' methods (because it cannot mutate it's contents).

Resources