Это можно сделать очень функциональным и быстрым способом, написав конвейер для обработки входных массивов:
let sortedArrayBasedOnMatches = [test1, test2] // initial unsorted array
.map { arr in (arr, arr.filter { controlArray.contains($0) }.count) } // making pairs of (array, numberOfMatches)
.sorted { $0.1 > $1.1 } // sorting by the number of matches
.map { $0.0 } // getting rid of the match count, if not needed
Обновление Как указано @ Carpsen90, Switf 5 поставляется споддержка count(where:)
, которая уменьшает количество кода, необходимого при первом вызове map()
.Решение, которое использует это, может быть записано в виде
// Swift 5 already has this, let's add it for current versions too
#if !swift(>=5)
extension Sequence {
// taken from the SE proposal
// https://github.com/apple/swift-evolution/blob/master/proposals/0220-count-where.md#detailed-design
func count(where predicate: (Element) throws -> Bool) rethrows -> Int {
var count = 0
for element in self {
if try predicate(element) {
count += 1
}
}
return count
}
}
#endif
let sortedArrayBasedOnMatches = [test1, test2] // initial unsorted array
.map { (arr: $0, matchCount: $0.count(where: controlArray.contains)) } // making pairs of (array, numberOfMatches)
.sorted { $0.matchCount > $1.matchCount } // sorting by the number of matches
.map { $0.arr } // getting rid of the match count, if not needed
Еще одно изменение стиля по сравнению с оригинальным решением состоит в использовании меток для компонентов кортежа, это делает код немного более понятным, нотакже немного более многословно.