Gagan_iOS
Gagan_iOS

Reputation: 4060

Sort Array of dictionary in Swift

I am getting an array from response as below

  items=[{
         "displayName": "Adam Codo",
         "postedTime": "2011-04-04T21:31:20.000Z",
         "message" : "Hello Test Message"
         },
         {
         "displayName": "Leena",
         "postedTime": "2011-04-04T20:32:20.000Z",
         "message" : " Start Hello Test Message"
         },
         {
         "displayName": "Zohn",
         "postedTime": "2011-04-03T22:47:20.000Z",
         "message" : "Hi Leena"
         },
         {
         "displayName": "Leena",
         "postedTime": "2011-04-04T21:32:20.000Z",
         "message" : " Start Hello Test Message"
         },
         {
         "displayName": "Adam Codo",
         "postedTime": "2011-04-04T22:13:10.000Z",
         "message" : "Hello Test Message"
         }]

I have so sort the array by the name & later by the time. so I need sorted array like below

  items=[
         {
         "displayName": "Adam Codo",
         "postedTime": "2011-04-04T22:13:10.000Z",
         "message" : "Hello reply Test Message"
         },
         {
         "displayName": "Adam Codo",
         "postedTime": "2011-04-04T21:31:20.000Z",
         "message" : "Hello Test Message"
         },
         {
         "displayName": "Leena",
         "postedTime": "2011-04-04T21:32:20.000Z",
         "message" : " Start Hello Test Message"
         },
         {
         "displayName": "Leena",
         "postedTime": "2011-04-04T20:32:20.000Z",
         "message" : " Start Hello Test Message"
         },
         {
         "displayName": "Zohn",
         "postedTime": "2011-04-03T22:47:20.000Z",
         "message" : "Hi Leena"
         }
]

Can anyone suggest me how to do this? Any idea would be great.

Upvotes: 0

Views: 110

Answers (3)

Luca Angeletti
Luca Angeletti

Reputation: 59496

Do NOT use dictionaries

Build your own model instead and life will be easier.

Here's the model

struct Element {
    let displayName: String
    let postedTime: Date
    let message: String

    init?(dict:[String:String]) {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
        guard
            let displayName = dict["displayName"],
            let timeText = dict["postedTime"],
            let postedTime = dateFormatter.date(from: timeText),
            let message = dict["message"]
            else { return nil }

        self.displayName = displayName
        self.postedTime = postedTime
        self.message = message
    }
}

Now let's make it Comparable

extension Element: Comparable {

    static func <(lhs: Element, rhs: Element) -> Bool {
        if lhs.displayName != rhs.displayName {
            return lhs.displayName < rhs.displayName
        }
        return lhs.postedTime < rhs.postedTime
    }

    static func ==(lhs: Element, rhs: Element) -> Bool {
        return lhs.displayName == rhs.displayName && lhs.postedTime < rhs.postedTime
    }

}

Now given your array of dictionaries

let items = [
    [
        "displayName": "Adam Codo",
        "postedTime": "2011-04-04T21:31:20.000Z",
        "message" : "Hello Test Message"
    ],
    [
        "displayName": "Leena",
        "postedTime": "2011-04-04T20:32:20.000Z",
        "message" : " Start Hello Test Message"
    ],
    [
        "displayName": "Zohn",
        "postedTime": "2011-04-03T22:47:20.000Z",
        "message" : "Hi Leena"
    ],
    [
        "displayName": "Leena",
        "postedTime": "2011-04-04T21:32:20.000Z",
        "message" : " Start Hello Test Message"
    ],
    [
        "displayName": "Adam Codo",
        "postedTime": "2011-04-04T22:13:10.000Z",
        "message" : "Hello Test Message"
    ]
]

we can convert it to an array of Element(s) and finally sorting it

let sortedElms = items.flatMap(Element.init).sorted()

Result

[
    Element(displayName: "Adam Codo", postedTime: 2011-04-04 21:31:20 +0000, message: "Hello Test Message"),
    Element(displayName: "Adam Codo", postedTime: 2011-04-04 22:13:10 +0000, message: "Hello Test Message"),
    Element(displayName: "Leena", postedTime: 2011-04-04 20:32:20 +0000, message: " Start Hello Test Message"),
    Element(displayName: "Leena", postedTime: 2011-04-04 21:32:20 +0000, message: " Start Hello Test Message"),
    Element(displayName: "Zohn", postedTime: 2011-04-03 22:47:20 +0000, message: "Hi Leena")
]

Upvotes: 2

ObranS
ObranS

Reputation: 210

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
                                    initWithKey: @"displayName" ascending: YES];

NSArray *sortedArray = [_locations sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

NSArray *sortedLocations = [_locations sortedArrayUsingComparator: ^(NSDictionary *d1, NSDictionary *d2) {
    ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
    NSDate *theDate1 = [formatter dateFromString:[d1 valueForKey:@"postedTime"]];
    NSDate *theDate2 = [formatter dateFromString:[d2 valueForKey:@"postedTime"]];
    return [theDate1 compare:theDate2];
}];

OR

NSArray *sortedLocations = [_locations sortedArrayUsingComparator: ^(NSDictionary *d1, NSDictionary *d2) {

    ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
    NSDate *theDate1 = [formatter dateFromString:[d1 valueForKey:@"postedTime"]];
    NSDate *theDate2 = [formatter dateFromString:[d2 valueForKey:@"postedTime"]];

    NSString *name1 = [d1 valueForKey:@"displayName"];
    NSString *name2 = [d2 valueForKey:@"displayName"];

    if ([name1 compare:name2]) {
        return [theDate1 compare:theDate2];
    }


    return NSOrderedDescending;
}];

But be awere I did not check it

Upvotes: 0

Mohamed Helmy
Mohamed Helmy

Reputation: 832

var sortedResults = items.sorted {
          (dictOne, dictTwo) -> Bool in 

    if dictOne["displayName"]! != dictTwo["displayName"]! {
            return dictOne["displayName"]! < dictTwo["displayName"]!
        }

        return dictOne["postedTime"]! < dictTwo["postedTime"]!
        };

Upvotes: 1

Related Questions