Reputation: 3350
I have an NSMutableDictionary
, that contains custom (PNMessage) objects that also contain an NSDictionary
and two other string object. Every key
represents a username and every object
represents a message, that belongs to a key.
I would like to copy the newest objects that belongs to a particular user (key) into a new NSMutableArray
. For example: i wanna copy the newest object that belongs to the key: Tim and Bill.
I know dictionaries are unsorted, but i store a string with the date in every dictionary (keyCreateDate) inside the objects, therefore it's possible to loop through them and identify the recent object.
This is how the sorted message dict looks like in the log:
{
tim = (
"PNMessage (0x1811a340): <message: {\n keyCreateDate = \"06/09/14 21:24\";\n keyMessage = \"Lorem ipsum\";\n keyRecieverChannel = bill;\n keySenderUser = tim;\n}, date: (null), channel: main>",
"PNMessage (0x16526ce0): <message: {\n keyCreateDate = \"06/09/14 21:31\";\n keyMessage = \"Lorem ipsum dolor\";\n keyRecieverChannel = tim;\n keySenderUser = bill;\n}, date: (null), channel: main>",
);
bill = (
"PNMessage (0x18109b00): <message: {\n keyCreateDate = \"06/08/14 21:23\";\n keyMessage = Hello World;\n keyRecieverChannel = bill;\n keySenderUser = tim;\n}, date: (null), channel: main>",
"PNMessage (0x18104070): <message: {\n keyCreateDate = \"06/09/14 21:23\";\n keyMessage = \"Hello Bill\";\n keyRecieverChannel = bill;\n keySenderUser = kyra;\n}, date: (null), channel: main>",
);
dave = (
"PNMessage (0x1811a340): <message: {\n keyCreateDate = \"06/09/14 21:24\";\n keyMessage = \"Lorem ipsum\";\n keyRecieverChannel = bill;\n keySenderUser = tim;\n}, date: (null), channel: main>",
"PNMessage (0x16526ce0): <message: {\n keyCreateDate = \"06/09/14 21:31\";\n keyMessage = \"Lorem ipsum dolor\";\n keyRecieverChannel = tim;\n keySenderUser = bill;\n}, date: (null), channel: main>",
);
}
And i need an array like this
NSMutableArray *sampleArray = @[newestObjectofTim, newestObjectofBill, newestObjectofDave];
I think i should loop through every key's every object, check the keyCreateDate
inside every object and add the recent to the sampleArray
. The key name that we need in the main dictionary is user
.
I started with this, but get stucked after the first lines. As a first step i tried to check every PNMessage
object in the self.messagesDictionary
(which has the user key) and then log the 1. object. It runs in the simulator, but i can't see the log, so it's sure that's wrong.
for(PNMessage *object in [self.messagesDictionary objectForKey:@"user"])
{
[object.message objectAtIndex:0];
NSLog(@"the object is %@", object.message);
}
UPDATE:
The accepted answer is correct, but Duncan's answer also contain useful, relevant suggestion.
Upvotes: 0
Views: 132
Reputation: 131418
It looks to me like your structure is a little different than your description. I see:
An outer dictionary, with keys like "tim", "bill", and "dave"
Each entry in your dictionary appears to be an array of PNMessage objects. You never mentioned the array.
In the small sample you posted, the array of message objects appears to be sorted in order of oldest created date to newest.
It isn't completely clear from your description how your PNMessage object is structured. Your log says the message objects contain values for "keyCreateDate" and "keyMessage". Does the PNMessage object contain a dictionary, and those are the keys that are in the dictionary in each message object?
Can you post the header for your PNMessage object class? And are you keys in the PNMessage "keyCreateDate" and "keyMessage" or "CreateDate" and "Message" (Do they have the prefix "key" or not?
If your arrays of messages are sorted oldest-to-newest as your data suggests then @ChrimsonChris's code is 99% of the way there. However, the last line should read
newestMessageByUser[user] = messages.lastObject;
(Since you said you wanted the newest message for each user in your outer dictionary of users and it looks to me like the first entry in each array is the oldest and the last entry is the newest.)
By the way, his for loop is a little confusing at first. The line
for (NSString *user in self.messagesDictionary)
Uses fast enumeration on a the outer dictionary.
If you search on the string "Using fast enumeration with a dictionary" in the Xcode docs, you will find this bit of information:
The behavior for fast enumeration varies slightly based on the type of collection. Arrays and sets enumerate their contents, and dictionaries enumerate their keys.
So that for loop will give you one key at a time from your outer dictionary.
If your message objects are not in an array, or the array is not sorted by create date, then you'll have to adapt ChrimsonChris's code.
Upvotes: 1
Reputation: 4641
Something like this will give you a dictionary containing the most recent message for each user string.
//Get newest message from each user. User(NSString *) => PNMessage*
NSMutableDictionary *newestMessageByUser = [NSMutableDictionary dictionary];
for (NSString *user in self.messagesDictionary) {
NSArray *messages = self.messagesDictionary[user];
newestMessageByUser[user] = messages.firstObject;
}
Upvotes: 1