Load UITableView sections by NSDate from NSDictionary? - ios

I have an NSArray of NSDictionaries in my app. In each dictionary I hold an NSDate called "RunDate." The problem I am having now is that the code I am trying to do it with is very inefficient. Basically I only want one section per date out of all the dictionaries. Then in each section (sorted by that date), I would load the appropriate dictionary that had that date.
In the code below I made a new NSArray of NSDictionarys which held a date and number of that date (so I could know how many rows are in each section). The problem is, this code looks and feels very inefficient and I was wondering if there were any ways my code is incorrect or could be improved upon. There can be over 500 entries and the code I have now would be very slow. Does anyone have any suggestions on it?
runArray = [[NSMutableArray alloc] init];
runArray = [[[NSUserDefaults standardUserDefaults] arrayForKey:#"RunArray"] mutableCopy];
runDictTableArray = [[NSMutableArray alloc] init];
for (NSDictionary *dict in runArray) {
NSDictionary *runInfoDict = [[NSMutableDictionary alloc] init];
NSDate *theDate = [dict objectForKey:#"RunDate"];
//Check if we already have this date in the saved run array
BOOL goToNextDict = FALSE;
for (NSDictionary *savedDict in runDictTableArray) {
if ([theDate compare:[savedDict objectForKey:#"RunDate"]] == NSOrderedSame) {
goToNextDict = TRUE;
break;
}
}
if (goToNextDict)
continue;
////////////////////////////
//Now we check how many more we have of this date
int numbOfDate = 1;
int index = (int)[runArray indexOfObject:dict];
for (int i = index; i < [runArray count]; i++) {
NSDictionary *dictInner = [runArray objectAtIndex:i];
if ([theDate compare:[dictInner objectForKey:#"RunDate"]] == NSOrderedSame) {
numbOfDate++;
}
}
////////////////////////////
[runInfoDict setValue:[NSNumber numberWithInt:numbOfDate] forKey:#"DateAmount"];
[runInfoDict setValue:theDate forKey:#"Date"];
[runDictTableArray addObject:runInfoDict];
}

Some suggestions:
You probably only need 1 NSMutableDictionary, rather than a NSMutableArray of NSDictionary. While looping through runArray, check if your dictionary has a value for your date (objectForKey returns a value). If it does, add 1 to the count. If it does not, add that date as a key to the dictionary with a value of 1. This way, you won't have to do the inner loop to get the number of times a date occurs. You won't need the 'go to next dictionary' logic either, I would think.
runArray = [[NSMutableArray alloc] init]; doesn't really do anything since you're immediately re-assigning runArray.
Consider using NSInteger over regular int, NSInteger will give you the appropriate size for whatever architecture your app is running on.
There's some cool syntax shortcuts you might like. You can avoid [runInfoDict setValue:[NSNumber numberWithInt:numbOfDate]... by simply writing [runInfoDict setValue:#(numbOfDate) ..., which will put the value into NSNumber for you.

Related

Strange dictionary sort ios objective c

I want to do kind of a weird dictionary sort. I have non-unique values and keys and get something like this
NSArray *counts = [#"1",#"2",#"2",#"3",#"6",#"10"];
NSArray *names =[#"Jerry",#"Marge",#"Jerry",#"Marge",#"Jen",#"Mark"];
The output that I want is an descending ordered list by counts with unique names. I don't want lower values of the same person in my outputted arrays. The output should be.
sortedNames=[#"Mark",#"Jen",#"Marge",#"Jerry"]
sortedCounts=[#"10",#"6",#"3",#"2"];
I would really appreciate some help on this.
NSMutableArray *userNameArray = [[NSMutableArray alloc] init];
NSMutableArray *countArray = [[NSMutableArray alloc] init];
for (NSDictionary *dict in bigDick) {
NSString *nameString =[dict objectForKey:#"Name"];
NSString *countString =[dict objectForKey:#"Count"];
NSInteger countInt = [countString integerValue];
NSNumber *countNumber =[NSNumber numberWithInt:countInt];
[userNameArray addObject:nameString];
[countArray addObject:countNumber];
}
NSArray *namesAscending =[[userNameArray reverseObjectEnumerator]allObjects];
NSArray *countsAscending=[[countArray reverseObjectEnumerator]allObjects];
// Put the two arrays into a dictionary as keys and values
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:countsAscending forKeys:namesAscending];
// Sort the first array
NSArray *sortedCountArray = [[dictionary allValues] sortedArrayUsingSelector:#selector(compare:)];
// Sort the second array based on the sorted first array
// NSArray *sortedNameArray= [dictionary objectsForKeys:sortedCountArray notFoundMarker:[NSNull null]];
NSMutableArray *nameArray =[[NSMutableArray alloc] init];
for (int i=1; i<sortedCountArray.count; i++) {
NSString *name = [dictionary allKeysForObject:sortedCountArray[i]];
if (sortedCountArray[i]!=sortedCountArray[i-1]) {
[nameArray addObject:name];
}
}
an old method is to manual sort the array with numbers, by searching on every iteraton for the biggest value, and when you find the max value take the name from the other vector at index of the max number and move it in new vector...
max = counts[0];
counter = 0;
for (int i=0;i<counts.count;i++)
{
temp = counts[i];
if (max<temp)
max = temp;
counter = i;
}
[new_names addObject: [names objectAtIndex:counter]];
[new_numbers addObject: max];
[numbers removeObjectAtIndex: counter];
[names removeObjectAtIndex:counter];
Try something like this. It should work if you do it this way.
Important! do not remove elements in for from array that you count for the for length.
Your problem is in your algorithm design, if you step through it a line at a time in the debugger you should see what it does and where it goes wrong.
We're not here to write you code, but let's see if we can go through one step of an algorithm to help you one your way:
Useful fact: If you lookup a key in a dictionary and that key does not exist the return value will be nil.
From this: you can use a dictionary to keep track of the names you have seen paired with the highest score so far. You obtain a name,score pair, lookup the name in the dictionary - if you get nil its a new name with a new high score. If it's not nil its the currently known high score, so you can compare and update.
That's a rough algorithm, let's try it. Before we start rather than using literal strings for keys everywhere let's define some constants. This has the advantage that we won't mistype the strings, the compiler will spot if we mistype the constant names. These can be defined at the file level or within a method:
const NSString *kName = #"Name";
const NSString *kCount = #"Count";
Now to the code, in a method somewhere, we'll need a dictionary:
NSMutableDictionary *highScores = [NSMutableDictionary new]; // a single dictionary rather than your two arrays
Now start your loop as before:
for (NSDictionary *dict in bigDict) // same loop as your code
{
and extract the two values as before:
NSString *nameString = dict[kName]; // same as your code, but using modern syntax
NSInteger countInt = [dict[kCount] integerValue]; // condense two lines of your code into one
Now we can lookup the name in our dictionary:
NSNumber *currentScore = highScores[nameString]; // get current high score for user, if any
If the name exists as a key this will return the current associated value - the score in this case, if there is no matching key this will return nil. We can test for this in a single if:
if (currentScore == nil // not seen user before, no high score
|| currentScore.integerValue < countInt) // seen user, countInt is greater
{
The above condition will evaluate to true if we either need to add the name or update its score. Adding & updating a key/value pair is the same operation, so we just need the line:
highScores[nameString] = #(countInt); // add or update score for user
and a couple of braces to terminate the if and for:
}
}
Let's see what we have:
NSLog(#"Output: %#", highScores);
This outputs:
Output: {
Jen = 6;
Jerry = 2;
Marge = 3;
Mark = 10;
}
Which is a step in the right direction. (Note: the dictionary is not sorted, NSLog just displays the keys in sorted order.)
Make sure you understand why that works, copy the code and test it. Then try to design the next phase of the algorithm.
If you get stuck you can ask a new question showing the algorithm and code you've developed and someone will probably help. If you do this you should include a link to this question so people can see the history (and know you're not trying to get an app written for you through multiple questions!)
HTH
Try this.
sortedArray = [yourArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
After sort your array then remove duplicates using following.
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray: sortedArray];
NSArray *arrayWithoutDuplicates = [orderedSet array];

Sorting custom objects in UITableView section

I'm making an app whereas I have created a custom class which inherits from NSObject. This class contains various properties whereas one of them is a NSDate property and another one is a NSString. I would like to sort these objects in a UITableView using sections whereas each section represents the month and year of the NSDate in the object. So far, I've only managed to populate the list using a detail UITableViewCell to show the information but I'm not sure how to go about using sections as they're dynamic and not static cells.
I kind of brainstormed solutions and one of them would be to create a for-loop for all the objects and count the number of months and return that number in the numberOfSectionsInTableView: method - but I'm far from certain if this is the best and most proper way of addressing it.
Could someone help me with this?
My custom objects contain various properties but these are the ones we need to focus on:
#property (nonatomic, strong) NSString *information;
#property (nonatomic, strong) NSDate *dateAdded;
Thank you!
Erik
So give your objects a yearAndMonth property. in the getter for the property, check the instance variable. If it's !0, return it. If it ==0, use NSCalendar to calculate the year and month, turn it into a number (year*100+month), save it in the ivar, and return it.
(Also make the setter on the date property zero out the yearAndMonth property.)
Now you can write code that breaks your table view into sections based on the value of this property. For any given object, it will only be calculated once, so it shouldn't impact performance over-much.
I think a lot of it is a matter of preference. In the past for something like this I would just create a two demential array. Where the array in the array would represent the section and when you need need a section header you pull that section array out and populate the header based on the first object in that array.
NSArray *sectionArray = [self arrayAfterSorting:customObjectArray];
//section would be something like this
NSArray *section = sectionArray[section];
return section.count;
//header
NSArray *section = sectionArray[section];
CustomObject *customObject = section[0];
return customObject.whateverHeaderShouldBeBasedOnObject;
I personally try to avoid having two separate arrays and prefer to have everything built into one two dimensional array. Hope that makes sense and helps.
Edit:
If the issue is figuring out how to sort I would look at this question and answer. Although they are talking about putting it into a dictionary I am sure you can apply the same logic to an array.
Sort NSArray with NSDate object into NSDictionary by month
Hope that helps.
is your Array which contains your custom Objects sorted? Probably not i guess. I'd first start with that:
NSArray *sortedObjectArray = [youArray sortedArrayUsingComparator:^NSComparisonResult(YourObjectClass *a, YourObjectClass *b) {
return [a.dateAdded compare:b.dateAdded];}];
As you now got that, it would be the best to actually find out how many table view sections you need. To loop through your sortedArray would be the best approach there. But keep in mind to do it e.g. in viewDidLoad or some place else, where you retrieve your data, to make sure that you actually perform your search and data aggregation only once.
Doing that in numberOfSectionsInTableView would cause your app to repeat all this unnecessary calculation each time the tableView is reloaded.
So, what about the sections right? I'd recommend an NSMutableArray which represent the sections you need. This object then should contain NSMutableArrays itself, which contain your custom Objects.
But first we need to find out how many section you will actually need.Just do a for loop like this:
NSMutableArray *dateArray = [[NSMutableArray alloc] init];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *recentDate;
for (YourObjectClass *object in sortedObjectArray) {
if (!recentDate) {
[dateArray addObject:object.dateAdded];
recentDate = object.dateAdded;
}
else {
NSDateComponents *currentDateComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:object.dateAdded];
NSDateComponents *recentDateComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:recentDate];
if (recentDateComponents.year != currentDateComponents.year || recentDateComponents.month != currentDateComponents.month) {
[dateArray addObject:object.dateAdded];
recentDate = object.dateAdded;
}
}
}
So now you got your dateArray which contains all distinct dates in terms of month and year.
NSMutableArray *finalArray = [[NSMutableArray alloc] init];
for (NSDate *date in dateArray) {
NSMutableArray *subArray = [[NSMutableArray alloc] init];
for (YourObjectClass *object in sortedObjectArray) {
NSDateComponents *currentDateComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:object.dateAdded];
NSDateComponents *recentDateComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];
if (recentDateComponents.year == currentDateComponents.year || recentDateComponents.month == currentDateComponents.month) {
[subArray addObject:object];
}
else {
break;
}
}
[finalArray addObject:subArray];
}
This should be it. Now just tell your tableView Datasource that you have finalArray.count sections. And in numberOfRowsInSection: you just get the subArray on the sectionIndex and return its count value. Hope this helps you out :)
(Didn't test the code, so be aware :))
I managed to put this code together that works, although I realised I might want to change the UI as the data wasn't presented as well as I initially thought. This is the code I made, all the other answers helped me with this!
// Create a sections NSMutableArray
_sectionsArray = [[NSMutableArray alloc] init];
// Cycle through the workdays and populate sectionsArray
NSString *currentMonth;
NSMutableArray *currentMonthArray = [[NSMutableArray alloc] init];
for (DayModel *currentModel in sortedWorkDays)
{
// Create a currentMonthArray and initialize it
// Initial currentMonth value
if (currentMonth == nil)
{
currentMonth = [self monthFromDate:currentModel.registerDate];
}
if ([currentMonth isEqualToString:[self monthFromDate:currentModel.registerDate]])
{
NSLog(#"current");
// Current month
[currentMonthArray addObject:currentModel];
if (([sortedWorkDays indexOfObject:currentModel] + 1) == [sortedWorkDays count])
{
// Complete
NSLog(#"LAST OF ALL");
[_sectionsArray addObject:currentMonthArray];
currentMonthArray = nil;
currentMonthArray = [[NSMutableArray alloc] init];
currentMonth = [self monthFromDate:currentModel.registerDate];
[currentMonthArray addObject:currentModel];
}
} else
{
// Finished with this month
NSLog(#"LAST");
[_sectionsArray addObject:currentMonthArray];
currentMonthArray = nil;
currentMonthArray = [[NSMutableArray alloc] init];
currentMonth = [self monthFromDate:currentModel.registerDate];
[currentMonthArray addObject:currentModel];
}
}

Tricky Object Sorting and Removing from NSMutableArray

I have an array of objects (that contain a message), every object has the same structure. It has a message property which is an NSDictionary. One dictionary looks like this:
<message: {
keyCreateDate = "06/08/14 21:23";
keyMessage = Lorem ipsum;
keyReceiverChannel = sampleString;
keySenderUser = SampleName;
},...
My goal is to make an "inbox" where i would like to display the newest messages from every user in each cell. I want the show only the newest messages from each user, like the Fb messages, What'sApp or iMessage inbox, every cell in the table view represents the recent message from a friend. It looks very easy, but it's much harder than i imaged. So i need to remove every message from every friend, but always keep newest one. Actually i can remove all message from one user, but can't keep the newest while removing the others. Is it possible to do this?
I can remove all message for one specified user with this code:
NSMutableArray *originalArray = [[NSMutableArray alloc]initWithArray:message];
NSMutableArray *objectsToRemove = [[NSMutableArray alloc]init];
NSMutableArray *cloneArray = [NSMutableArray arrayWithArray:originalArray];
for (NMessage *messageObject in originalArray) {
if ([messageObject.message[#"keySenderUser"] isEqual:usernameString]) {
[objectsToRemove addObject:messageObject];
}
}
if ([objectsToRemove count]>0) {
[cloneArray removeObjectsInArray:objectsToRemove];
NSLog(#"deleted: %#", objectsToRemove);
self.messagesArray = [[NSMutableArray alloc]initWithArray:cloneArray];
I think it would be the easier, if i could somehow add an exception to the [cloneArray removeObjectsInArray:objectsToRemove]; line, that doesn't let to remove the newest ones. But it's also a problem that i need to sort the messages based on the keySenderUser before i delete them. My actual code can't do that, it can find only one pre-defined user's message and remove all of them. Please share with me if you have any idea. Thanks in advance.
I feel bottom up is better in your case where you build a new array which contains latest message dictionary.
The solution is as below.
1. sort the array using date.
2. Create a new list for holding user messages.
2. Loop through each object check whether the user is already present, If not add it to the created list.
The code solution is below, pass in your array of messaged, which would give a list of messages which are latest for an user.
-(NSArray *) GetLatestMessageListForEveryUser:(NSArray *) array
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDate *obj1Date = [formatter dateFromString: [(NSDictionary *)obj1 objectForKey:#"keyCreateDate" ] ];
NSDate *obj2Date = [formatter dateFromString:[(NSDictionary *)obj2 objectForKey:#"keyCreateDate" ] ];
return ([obj1Date earlierDate:obj2Date] == obj1Date);
}];
NSMutableArray *messageArray = [NSMutableArray array];
NSMutableArray *usersArray = [NSMutableArray array];
for (NSDictionary *messageDictionary in sortedArray)
{
NSString *userName = [messageDictionary objectForKey:#"keySenderUser"];
if (![usersArray containsObject:userName])
{
[usersArray addObject:userName];
[messageArray addObject:messageDictionary];
}
}
return messageArray;
}

Iterating through an NSArray and storing items in groups of 12

I've definitely tried to do my due diligence on this one but keep coming up short. I have an array of objects that I have parsed and I want to iterate through these and store them. Assuming the array is 144 objects (just an example), I want to store it in groups of 12 to display in a tableview cell. Actually of those 12 objects in the array I'll likely only be displaying 3-4 in the cell, but all of those objects in the detail view.
To help explain what I mean (sorry if it hasn't made sense at this point) here's some of the code I've got that is getting the data.
NSMutableArray *objectsArray = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in objectsNode) {
PHSingleEvent *singleEvent = [[PHSingleEvent alloc]init];
[objectsArray addObject:singleEvent];
singleEvent.title = [[element firstChild] content];
}
This pulls down the entire array of objects (an unknown number but definitely a multiple of 12). How would I go about storing 12 objects at a time into a single event?
I can log the info with
PHSingleEvent *firstObject = [objectsArray objectAtIndex:0] // this one is null
PHSingleEvent *eventStartTime = [objectsArray objectAtIndex:1];
PHSingleEvent *eventEndTime = [objectsArray objectAtIndex:2];
...
PHSingleEvent *lastObject = [objectsArray objectAtIndex:11];
NSLog(#"single object of event: %#", eventStartTime.startTime);
NSLog(#"single object of event: %#", eventEndTime.endTime);
etc...
But the array keeps going past 12. I want to iterate up through each 12 objects and store those values, preferably as strings to be displayed in a cell and detail view.
Any ideas?
Thanks much in advance and I will be here to answer any questions if I was unclear.
C.
How about using a for loop? Assuming that each event object has 12 sub-objects (i.e. indices 0 - 11) you could achieve storing it by using a mod function. For example:
NSMutableArray *eventArray = [[NSMutableArray alloc] init];
for(int i=0; i<objectArray.count/12;i++){
int offset = 12*i;
NSMutableArray *event = [objectsArray subarrayWithRange:NSMakeRange(offset, 12)];
[eventArray addObject:event];
}
So now eventArray has n arrays, each of 12 objects (where n = totalObjects/12)
EDIT: A better idea would be to use NSDictionary. For example:
NSMutableArray *eventArray = [[NSMutableArray alloc] init];
for(int i=0; i<objectArray.count/12;i++){
int offset = 12*i;
NSDictionary *tempDict = [[NSDictionary alloc] initWithObjectsAndKeys: [objectsArray objectAtIndex: offset], #"eventStartTime", [objectsArray objectAtIndex: offset+1], #"eventEndTime", ..., [objectsArray objectAtIndex: offset+11, #"lastObject",nil];
[eventArray addObject:tempDict];
}
Then you can access each of the above objects using a similar statement as shown below:
PHSingleEvent *eventStartTime = [[eventArray objectAtIndex: index] objectForKey: #"eventStartTime"];
Hope this helps
This method will return an array of smaller arrays based on the group size you specify.
- (NSMutableArray*)makeGroupsOf:(int)groupSize fromArray:(NSArray*)array
{
if (!array || array.count == 0 || groupSize == 0)
{
return nil;
}
NSMutableArray *bigGroup = [[NSMutableArray alloc] init];
for (int i = 0; i < array.count; )
{
NSMutableArray *smallGroup = [[NSMutableArray alloc] initWithCapacity:groupSize];
for (int j = 0; j < groupSize && i < array.count; j++)
{
[smallGroup addObject:[array objectAtIndex:i]];
i++;
}
[bigGroup addObject:smallGroup];
}
return bigGroup;
}
I haven't tested it or anything though. After you have the big array with the smaller array(s) it is just a matter of filling each cell with any desired number of objects from the sub arrays.
Note: You might want to handle the cases when the array is empty, null or the group size is 0 differently.

Multiple dictionaries within an array and Checking for duplicate keys - Objective C

I have an array which contains multiple Dictionaries each one with 3 keys (#"date", #"username", #"text").
What I want to check for, is whether the same user (#"username") exists in more than one dictionary in that Array. And, if she does, combine the text for those "duplicates" into one dictionary.
I have considered this answer to check for duplicates and this one
but I cannot figure out how to combine these two.
Jumping in here because although I think you should work on the code yourself first, I think Miro's answer is more complicated than the issue requires and though I like the idea of using predicates in Greg's answer, here's a 3rd solution that (1) wouldn't require you to change your data structure and (2) references the necessary loops...
The way I'd do it: Create an NSMutableArray then start adding the usernames in order. If the NSMutableArray already contains the username though, don't add another instance of the username, but instead merge the dictionary info.
ex.
// Note: I'm calling your array of user dictionaries userArray.
// Create a username array to store the usernames and check for duplicates
NSMutableArray *usernames = [[NSMutableArray alloc] init];
// Create a new userArray to store the updated dictionary info, merged
// entries et. al.
NSMutableArray *newUserArray = [[NSMutableArray alloc] init];
// Go through the array of user dictionaries
for (NSDictionary *userDict in userArray) {
// If the usernames array doesn't already contain the username,
// add it to both the usernames array and the newUserArray as is
if (![usernames containsObject:[userDict objectForKey:#"username"]]) {
[usernames addObject:[userDict objectForKey:#"username"]];
[newUserArray addObject:userDict];
}
// Otherwise, merge the userArray entries
else {
// Get a mutable copy of the dictionary entry at the first instance
// with this username
int indexOfFirstInstance = [usernames indexOfObject:[userDict objectForKey:#"username"]];
NSMutableDictionary *entry = [[newUserArray objectAtIndex:indexOfFirstInstance] mutableCopy];
// Then combine the "text" or whatever other values you wanted to combine
// by replacing the "text" value with the combined text.
// (I've done so with a comma, but you could also store the value in an array)
[entry setValue:[[entry objectForKey:#"text"] stringByAppendingString:[NSString stringWithFormat:#", %#", [userDict objectForKey:#"text"]]] forKey:#"text"];
// Then replace this newly merged dictionary with the one at the
// first instance
[newUserArray replaceObjectAtIndex:indexOfFirstInstance withObject:entry];
}
}
Maybe something like this [untested] example? Loop through, maintain a hash of existing items, and if a duplicate is found then combine with existing and remove.
NSMutableArray main; // this should exist, with content
NSMutableDictionary *hash = [[NSMutableDictionary alloc] init];
// loop through, backwards, as we're attempting to modify array in place (risky)
for(int i = [main count] - 1; i >= 0; i--){
// check for existing
if(hash[main[i][#"username"]] != nil){
int existingIdx = [hash[main[i][#"username"]] integerValue]; // get existing location
main[existingIdx][#"text"] = [main[existingIdx][#"text"] stringByAppendingString:main[i][#"text"]]; // "combine text" .. or however you'd like to
[main removeObjectAtIndex:i]; // remove duplicate
} else {
[hash setValue:[[NSNumber alloc] initWithInt:i] forKey:main[i][#"username"]]; // mark existance, with location
}
}
If you use NSMutableDictionary, NSMutableArray and NSMutableString you can do it with predicate like that:
NSMutableDictionary *d1 = [#{#"username": #"Greg", #"text" : [#"text 1" mutableCopy]} mutableCopy];
NSMutableDictionary *d2 = [#{#"username": #"Greg", #"text" : [#"text 2" mutableCopy]} mutableCopy];
NSMutableDictionary *d3 = [#{#"username": #"John", #"text" : [#"text 3" mutableCopy]} mutableCopy];
NSMutableArray *array = [#[d1, d2, d3] mutableCopy];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"username = %#", #"Greg"];
NSArray *filterArray = [array filteredArrayUsingPredicate:predicate];
NSMutableDictionary * firstDict = filterArray[0];
for (NSDictionary *d in filterArray)
{
if (firstDict != d)
{
[firstDict[#"text"] appendString:d[#"text"]];
[array removeObject:d];
}
}

Resources