gpt4 book ai didi

swift - 在 Swift 中按类型和属性对异构集合进行排序

转载 作者:可可西里 更新时间:2023-11-01 00:28:23 25 4
gpt4 key购买 nike

我有一个不同类型的异构集合,它们都符合相同的协议(protocol)。我想按类型对数组进行排序,然后按名称属性对数组进行排序。例如,我希望这个动物数组按以下顺序按类型排序:狗、鸟,然后是鱼,如果它们属于同一类型,我想按名称排序。这是代码:

import Foundation

protocol Animal {
var name: String { get set }
}

class Dog: Animal {
var name: String

init(name: String) {
self.name = name
}
}

class Bird: Animal {
var name: String

init(name: String) {
self.name = name
}
}

class Fish: Animal {
var name: String

init(name: String) {
self.name = name
}
}

let dogA = Dog(name: "A")
let dogB = Dog(name: "B")
let birdA = Bird(name: "A")
let birdB = Bird(name: "B")
let fishA = Fish(name: "A")
let fishB = Fish(name: "B")

let animals: [Animal] = [fishB, fishA, birdB, birdA, dogB, dogA]

let sortedAnimals = animals.sorted { first, second -> Bool in
if first is Dog && !(second is Dog) {
return true
} else if first is Dog && second is Dog {
return first.name < second.name
}

if first is Bird && !(second is Bird) {
return true
} else if first is Bird && second is Bird {
return first.name < second.name
}

if first is Fish && !(second is Fish) {
return true
} else if first is Fish && second is Fish {
return first.name < second.name
}

return first.name < second.name
}

sortedAnimals

这有效,并产生正确的排序顺序:

{name "A", type "Dog"}
{name "B", type "Dog"}
{name "A", type "Bird"}
{name "B", type "Bird"}
{name "A", type "Fish"}
{name "B", type "Fish"}

但由于在生产代码中我有超过 30 种不同的类型在集合中,这种重复感觉非常重复。如果没有那么多重复代码,我如何才能完成这种排序?

最佳答案

使用 [Animal.Type] 建立排序,然后先比较类型是否相等,以决定是否需要按 name 排序>类型

let order: [Animal.Type] = [Dog.self, Bird.self, Fish.self]

let sortedAnimals = animals.sorted { first, second -> Bool in
let firstIndex = order.firstIndex { $0 == type(of: first) } ?? Int.max
let secondIndex = order.firstIndex { $0 == type(of: second) } ?? Int.max

if firstIndex == secondIndex {
return first.name < second.name
} else {
return firstIndex < secondIndex
}
}

注意事项:

  1. 如所写,缺失的类型将按 name 排序到数组末尾。
  2. 您可能想要添加:

    assert(firstIndex != Int.max, "missing type \(type(of: first)) from order array")
    assert(secondIndex != Int.max, "missing type \(type(of: second)) from order array")

    捕捉 order 数组中缺失的类型。虽然您可以强制展开 firstIndex(where:) 的结果,但 assert 提供了在 Debug 构建中查找缺失类型的能力,但是在 Release 版本中消失。

  3. 元组比较(如@Hamish 用 this answer 解释的那样)可用于将上面的 if 语句替换为:

    return (firstIndex, first.name) < (secondIndex, second.name)

    感谢@MartinR 的提醒!

关于swift - 在 Swift 中按类型和属性对异构集合进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54598618/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com