阵列无法正确排序:Swift 4

时间:2018-01-11 04:31:07

标签: arrays swift sorting swift4

我试图对一系列自定义对象进行排序,但出于某种原因,几周前工作的代码再也无法工作了。它应该检查$ 0和$ 1是否有相同的日期,如果他们这样做,它应该按ID排序数组,但目前它不能正确排序,当我打印数组时,我得到以下输出:

11-07-2017 : 1
11-07-2017 : 10
11-07-2017 : 11
11-07-2017 : 12
11-07-2017 : 13
11-07-2017 : 14
11-07-2017 : 15
11-07-2017 : 16
11-07-2017 : 17
11-07-2017 : 18
11-07-2017 : 19
11-07-2017 : 2
11-07-2017 : 20
11-07-2017 : 3
11-07-2017 : 4
11-07-2017 : 5
11-07-2017 : 7
11-07-2017 : 8
11-07-2017 : 9
11-08-2017 : 1
11-08-2017 : 2
11-09-2017 : 1
11-09-2017 : 2

从上面可以看出,只有少数条目的日期排序正确,但是条目较多的日期(11-07-17)没有。

以下是我的代码:

数组模型:

struct BalanceUser {

    var id = ""

    var name = ""

    var date = ""

}

当前排序代码:

self.sortedTableArray.sort(by: {
       if $0.date != $1.date {
             return $0.date < $1.date
       } else {
             return $0.id < $1.id
       }
})

Firebase代码(按要求):

ref.child("Admin").child("Balances").observeSingleEvent(of: .value, with: { (snapshot) in

        let value = snapshot.value as? NSDictionary

        if value!.count > 1 {

            let specificValues = value?.allKeys

            for balanceUser in specificValues! {

                var user = BalanceUser()

                user.date = balanceUser as! String

                if balanceUser as? String != "balance" {

                    var i = 0

                    var counter = 0

                    while i < 101 {

                        self.ref.child("Admin")
                            .child("Balances")
                            .child(balanceUser as! String)
                            .child(String(i))
                            .observeSingleEvent(of: .value, with: { (snapshot) in

                                let nameValue = snapshot.value as? NSDictionary

                                if nameValue != nil {

                                    user.id = counter

                                    var j = 0

                                    while j < (nameValue?.count)! {

                                        let item = nameValue?.allKeys[j] as? String

                                        var aItem = ""

                                        if let item = nameValue?.allValues[j] as? String {

                                            aItem = item

                                        } else if let item = nameValue?.allValues[j] as? NSNumber {

                                            aItem = String(describing: item)

                                        } else if let item = nameValue?.allValues[j] as? Int {

                                            aItem = String(describing: item)

                                        }


                                        if item == "name" {

                                            user.name = aItem

                                        } else if item == "money" {

                                            user.money = aItem

                                        } else if item == "balance" {

                                            user.balance = aItem

                                        } else if item == "status" {

                                            user.status = aItem

                                        }

                                        j += 1

                                    }


                                    let dateFormatter = DateFormatter()

                                    dateFormatter.dateFormat = "MM-dd-yyyy"

                                    if user.date.components(separatedBy: "-")[0] == dateFormatter.string(from: Date()).components(separatedBy: "-")[0] {

                                        self.sortedTableArray.append(user)

                                        self.sortedTableArray.sort(by: { (object1, object2) -> Bool in

                                            if object1.date == object2.date {

                                                return object1.id < object2.id

                                            } else {

                                                return object1.date < object2.date

                                            }

                                        })

                                    }

                                    self.tableArray.append(user)

                                    self.tableArray.sort(by: { (object1, object2) -> Bool in

                                        if object1.date == object2.date && object1.year == object2.year {

                                            return object2.id > object1.id

                                        } else {

                                            return object1.date < object2.date || object1.year < object2.year

                                        }

                                    })

                                    self.tableView.reloadData()

                                }

                                counter += 1

                            }) { (error) in

                                print(error.localizedDescription)

                        }

                        i += 1

                    }

                }

            }

        } else {

            self.view.makeToast(message: "No Users Found in Database")

        }

    }) { (error) in

        print(error.localizedDescription)

    }

4 个答案:

答案 0 :(得分:2)

在编写时,它的排序绝对正确。

字符串从头开始比较每个字符的工作。如果第一个字符相等,则检查第二个,依此类推。 在你的结果“10”&lt; “2”,导致“1”的字符 - 字符小于“2”字符代码。

你需要比较这样做:

self.sortedTableArray.sort(by: {
   if $0.date != $1.date {
         return $0.date < $1.date
   } else {
         return Int($0.id) ?? 0 < Int($1.id) ?? 0
   }
})

此外,您应该将日期比较为Date而不是字符串。

答案 1 :(得分:1)

您可以扩展BalanceUser添加计算属性以返回年,月,日和ID值。接下来只需使您的结构符合Comparable协议:

extension BalanceUser: Comparable {
    var year: Int {
        return Int(date.suffix(4))!
    }
    var month: Int {
        return Int(date.prefix(2))!
    }
    var day: Int {
        return Int(date.prefix(5).suffix(2))!
    }
    var idValue: Int {
        return Int(id)!
    }
    static func ==(lhs: BalanceUser, rhs: BalanceUser) -> Bool {
        return lhs.date == rhs.date && lhs.id == rhs.id
    }
    static func <(lhs: BalanceUser, rhs: BalanceUser) -> Bool {
        return (lhs.year, lhs.month, lhs.day, lhs.idValue) < (rhs.year, rhs.month, rhs.day, rhs.idValue)
    }
}

现在您可以简单地对自定义类型数组进行排序:

sortedTableArray.sort()

答案 2 :(得分:1)

只需使用正确排序数字字符串的字符串比较器

compare

或带有选项.numeric

的标准return $0.id.compare($1.id, options: .numeric) == .orderedAscending 选择器
{{1}}

答案 3 :(得分:0)

请检查以下代码:

let array = ["11-07-2017", "14-07-2017", "10-07-2017","08-07-2017"]
var convertedArray: [Date] = []

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"// yyyy-MM-dd"

for dat in array {
    let date = dateFormatter.date(from: dat)
       if let date = date {
            convertedArray.append(date)
        }
    }

var ready = convertedArray.sorted(by: { $0.compare($1) == .orderedDescending })

print(ready)