0

I have an array of files. The file conforms to the below File class:

class File {
   var name: String?    
   var type: String?
   var timeStamp: Date?
}

let array = [file1,file2,file3,file4]

The type could have values "dir" , "jpg", "png" , "mov"

I now want to sort the array based on type, name and datestamp. First I want to group files of similar types. For example, dir files should come first then the other ones. Now, I want to sort dir type files based on names and the othe file types based on the datestamp.

I was writing this code:

self.directoryContents = self.directoryContents?.sorted(by: { (file1, file2) -> Bool in

                        if file1.type == file2.type {
                            return file1.name! > file1.name!
                        }else {
                            return file1.timeStamp! > file2.timeStamp!
                        }

                    })

I am not able to achieve the desired sorting. Any help would be really appreciated.

Amrit Sidhu
  • 1,870
  • 1
  • 18
  • 32
  • 1
    Why `dir` files should be first? If not, what's the logic? If it's not working it's because you are missing cases. – Larme Mar 27 '18 at 12:16
  • @Larme Is right , Your logic is not clear about `type` – Prashant Tukadiya Mar 27 '18 at 12:19
  • Because I need to place dir files on the top then the other files. – Amrit Sidhu Mar 27 '18 at 12:20
  • @AmritSidhu are you using swift 4 ? – Prashant Tukadiya Mar 27 '18 at 12:20
  • I have 4 types of files. I need to sort all of them. First the sort should be based on dir types, then based on other types. Is it making sense now? – Amrit Sidhu Mar 27 '18 at 12:21
  • Yes, I am using swift 4. – Amrit Sidhu Mar 27 '18 at 12:22
  • Is this https://pastebin.com/z0RqDCLf what you expect ? – Larme Mar 27 '18 at 12:22
  • Related: [Swift - Sort array of objects with multiple criteria](https://stackoverflow.com/questions/37603960/swift-sort-array-of-objects-with-multiple-criteria). – Martin R Mar 27 '18 at 12:24
  • @Larme: Its something similar to your code. But the typeOrder could be varying. There could be a lot many types of files in the future. – Amrit Sidhu Mar 27 '18 at 12:26
  • Well you need to define how to order your type files because it seems to be one of the priority. Except if you care only about the "dir" files. – Larme Mar 27 '18 at 12:29
  • For now I only care for dir files as they need to be at the top but in future the priorities could change for different types as well. – Amrit Sidhu Mar 27 '18 at 12:31
  • 1
    You should think about whether the properties really need to be optional. Can a file have no name, type, or timestamp? If not, making them non-optional considerably simplifies the logic. – Martin R Mar 27 '18 at 12:37
  • They won't be nil but still, I think its safe as the contents are fetched from the directory. What if I get a nil value. – Amrit Sidhu Mar 27 '18 at 12:41
  • 1
    Either they cannot be nil, then make them non-optional. Or they can be nil, then you have to account for that case in the comparison function, instead of forced unwrapping. – Martin R Mar 27 '18 at 12:44
  • Let's make them non-optional. :). The answer worked for me, but still looking for the best sort. – Amrit Sidhu Mar 27 '18 at 12:45

1 Answers1

0

This should do the trick for all cases.

extension File {

    static func < (lhs: File, rhs: File) -> Bool {

        // name/date comparison logic
        let sortByNameThenDate: (File, File) -> Bool = { file1, file2 in
            if file1.name! == file2.name! {
                return file1.timeStamp! < file2.timeStamp!
            } else {
                return file1.name! < file2.name!
            }
        }

        // overall comparison logic
        if lhs.type! == rhs.type! {
            return sortByNameThenDate(lhs, rhs)
        } else if lhs.type! == "dir" {
            return true
        } else if rhs.type! == "dir" {
            return false
        } else {
            return lhs.type! < rhs.type!
        }
    }
}

Use like:

self.directoryContents = self.directoryContents?.sorted(by: { $0 < $1 })
John Snow
  • 452
  • 3
  • 5
  • @JohnSnow: Your answer works well! Thanks, man! But still, I think there could a better sort algorithm. You saved my time BTW. – Amrit Sidhu Mar 27 '18 at 12:43