将一个字符串数组排序以匹配另一个字符串数组



让一个数组匹配另一个数组的最简洁的排序方法是什么呢?

的例子:

public class Account {
    public var identifier: String
    init(id identifier:String) {
        self.identifier = identifier
    }
}

let knownOrder = ["abc", "klm", "def", "hij"]
var givenOrder = [Account(id: "abc"), Account(id: "def"), Account(id: "hij"), Account(id: "klm")]

在不改变已知顺序的情况下,使给定顺序的输出匹配已知顺序的最简单方法是什么?

为示例添加了更多内容。我试图获得具有标识符属性的给定帐户对象列表与存储的字符串列表的顺序相同,这些字符串与用户偏好匹配,以便拥有他们的帐户

你需要这样的东西吗?

let knownOrder = ["a1", "b2", "c3", "d4"]
var givenOrder = ["c3", "a1", "d4", "b2"]
givenOrder.sort { (lhs, rhs) -> Bool in
    (knownOrder.index(of: lhs) ?? 0) < (knownOrder.index(of: rhs) ?? 0)
}

?? 0存在,以防givenOrder包含不在knownOrder中的值,这些值将在列表开始时无序

您可以使用:

givenOrder = givenOrder.sort({ 
    (knownOrder.indexOf($0.identifier) ?? 0) < 
    (knownOrder.indexOf($1.identifier) ?? 0) 
})

如果您确信knownOrder将包含所有标识符(并且不担心如果不包含可能的崩溃),则可以将其压缩为:

givenOrder = givenOrder.sort({ 
    knownOrder.indexOf($0.identifier)! < 
    knownOrder.indexOf($1.identifier)!
})

在Swift 5中,index(of:)已被firstIndex(of:):

取代。
let results = givenOrder.sorted {
    (knownOrder.firstIndex(of: $0. identifier) ?? 0) < (knownOrder.firstIndex(of: $1. identifier) ?? 0)
}

请注意,firstIndex(of:)(以前称为index(of:))是0 (n),在sorted闭包中重复这样做有点低效。您可能想要构建一个字典:

let order = Dictionary(uniqueKeysWithValues: knownOrder.enumerated().map { ($0.1, $0.0) })

然后当你在order字典中查找每个对象的顺序时,你现在享受0(1)的性能:

let results = givenOrder.sorted {
    (order[$0.identifier] ?? 0) < (order[$1.identifier] ?? 0)
}

最简单的方法是使用"for in"

let knownOrder = ["a1", "b2", "c3", "d4"]
var givenOrder = ["c3", "a1", "d4", "b2"]
var result = [String]()
for item in knownOrder {
    if let index = givenOrder.index(of: item) {
        result.append(item)
        givenOrder.remove(at: index)
    }
}
for item in givenOrder {
    result.append(item)
}
print(result)

循环knownOrder中的每一项,如果该项也包含在givenOrder中,则将其添加到result中,并从givenOrder中删除。

然后将givenOrder的左侧项添加到结果中。

很容易理解,但是如果你有一个大数据,代码可能会很慢

您可以创建一个可订阅的类来管理帐户,尽管我不确定在字典中搜索大数据有多慢…

class AccountManager {
var accounts: [String: Account]
init(accounts: [Account]) {
    var accountDict = [String: Account]()
    for i in accounts {
        accountDict[i.identifier] = i
    }
    self.accounts = accountDict
}
func sort(by ids: [String]) -> [Account] {
    return ids.map({accounts[$0]}).flatMap({$0})
}
subscript(id: String) -> Account? {
    return accounts[id]
}
}

相关内容

最新更新