【问题标题】:Swift - array of tuples or struct of arrays for classification?Swift - 用于分类的元组数组或数组结构?
【发布时间】:2021-08-10 20:34:06
【问题描述】:

我正在实施一种搜索算法,我想显示从最相关到​​最不相关的结果。我有一组配置文件,我想从中获取配置文件 ID 的OrderedSet,按相关性排序。我的分类,从最相关到​​最不相关,是:

  • completeMatch
  • firstWordMatch
  • notFirstWordMatch
  • firstWordContains
  • notFirstWordContains
  • socialContains

我可以在个人资料上致电profiles.reduce(into: // Intermediate model) { ... } 来执行此操作。但是,我想知道我的中间模型应该是什么,然后我会将其转换为配置文件 ID 的 OrderedSet

  • 由配置文件 ID 和分类组成的元组数组作为枚举:
enum SearchResult: Int {
    case completeMatch = 0
    case firstWordMatch = 1
    case notFirstWordMatch = 2
    case firstWordContains = 3
    case notFirstWordContains = 4
    case socialContains = 5
}

let results: [(Profile.ID, SearchResult)] = profiles
                .reduce(into: [(SentProfile.ID, SearchResult)]()) { /* ... */ }

searchResults: OrderedSet<Profile.ID> = .init(
    results
        .sorted { lhs, rhs in
            let (_, lhsClassification) = lhs
            let (_, rhsClassification) = rhs
            return lhsClassification.rawValue < rhsClassification.rawValue
        }
        .map { profileID, _ in profileID }
)
  • 或将每个分类的结构作为独立的有序集:
struct SearchResult {
    var completeMatch: OrderedSet<SentProfile.ID> = []
    var firstWordMatch: OrderedSet<SentProfile.ID> = []
    var notFirstWordMatch: OrderedSet<SentProfile.ID> = []
    var firstWordContains: OrderedSet<SentProfile.ID> = []
    var notFirstWordContains: OrderedSet<SentProfile.ID> = []
    var socialContains: OrderedSet<SentProfile.ID> = []
    
    func joined() -> OrderedSet<SentProfile.ID> {
        return completeMatch
            .union(completeMatch)
            .union(firstWordMatch)
            .union(notFirstWordMatch)
            .union(firstWordContains)
            .union(notFirstWordContains)
            .union(socialContains)
    }
}

let results: SearchResult = profiles
                .reduce(into: SearchResult()) { /* ... */ }

searchResults = searchResults.joined()

我主要关心的是时间复杂度,我似乎无法确定两者之间哪个更好。

【问题讨论】:

  • 在最近的 SDK 中枚举自动合成 Comparable,因此您可以直接比较它们而无需访问它们的原始值(因为它们默认从 0 开始,您甚至不需要指定它们的原始值,甚至使它们符合 Int)

标签: swift time-complexity


【解决方案1】:

在结构中创建、填充然后合并多个集合感觉比对元组排序要重得多。您还可以通过减少创建中间数据结构的工作来简化所涉及的工作:

enum SearchResult: Comparable {
   case completeMatch
   case firstWordMatch
   case notFirstWordMatch
   case firstWordContains
   case notFirstWordContains
   case socialContains
}

// as before, just naming the tuple's elements for clarity in the example
let results: (id: Profile.ID, match: Searchresult) = ... 


let ordered: NSOrderedSet = .init(
   array: results.sorted(by: {$0.match < $1.match})
      .map{$0.id}
)

这直观地感觉不那么复杂,因为操作的数量减少到一个简单的排序(编译器将优化)然后是一个映射。它当然更容易阅读和维护。

【讨论】:

    猜你喜欢
    • 2022-06-17
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    • 2021-03-20
    • 2021-03-01
    相关资源
    最近更新 更多