Swift:按字母顺序对对象数组进行排序,但将匹配特定字段的对象放在首位

huangapple go评论56阅读模式
英文:

Swift: Sort array of objects alphabetically, but Put Objects Matching a particular Field First

问题

我有这个位置的结构体:

struct Location: Identifiable, Codable {
    var id: String
    var name: String
    var country: String
}

我可以轻松按名称排序:

self.userData = self.userData.sorted(by: {$0.name < $1.name })

但我还想能够将具有特定国家的位置放在列表的最前面。

我尝试了这个:

self.userData.sorted(by: { ($0.country == "United States"), ($0.name < $1.name) })

但我得到一个错误:“一行上的连续语句必须用;分隔”。

如何按特定国家的字母顺序排列?然后按名称属性的字母顺序排列其余位置。

英文:

I have this struct of locations:

struct Location: Identifiable, Codable {
    var id: String
    var name: String
    var country: String
}

I can easily sort this by name:

self.userData = self.userData.sorted(by: {$0.name < $1.name })

But I also want the ability to put locations with a particular country first in the list.

I tried this:

self.userData.sorted(by: { ($0.country == "United States"), ($0.name < $1.name) })

but I get an error "Consecutive statements on a line must be separated by ;".

How can I sort alphabetically by a particular country first? Then sort the remaining locations alphabetically by the name property.

答案1

得分: 2

如果两个地点的country都是"United States",那你可能仍然想按name排序。

let topCountries: Set<String> = ["United States"]

userData.sorted { a, b in
    switch (topCountries.contains(a.country), topCountries.contains(b.country)) {
    case (true, false): return true
    case (false, true): return false
    default: return a.name < b.name
    }
}
英文:

You probably still want to sort by name if both locations have a country of "United States".

let topCountries: Set<String> = ["United States"]

userData.sorted { a, b in
    switch (topCountries.contains(a.country), topCountries.contains(b.country)) {
    case (true, false): return true
    case (false, true): return false
    default: return a.name < b.name
    }
}

答案2

得分: 0

查看传递闭包的完整语法。您正在使用一种快捷方式,用于闭包仅由一个返回语句组成的特殊情况。将其扩展为完整的闭包语法,其中可以使用任意代码,然后编写您需要的代码。

英文:

Look at the full syntax of passing a closure. You are using a shortcut for the special case that the closure consists of one return statement only. Expand it to the full closure syntax where you can use arbitrary code, then write the code you need.

答案3

得分: 0

解决方案@rob给出的方法有效。以下是我的最终代码:

let topCountries: Set<String> = ["美国"] // 或者用户的国家

filteredLocations = allLocations.filter { $0.name.contains(searchText) }.sorted { a, b in
    switch (topCountries.contains(a.country), topCountries.contains(b.country)) {
        case (true, false): return true
        case (false, true): return false
        default: return a.name < b.name
    }
}
英文:

The solution @rob mayoff gave worked. Here is my final piece of code:

let topCountries: Set&lt;String&gt; = [&quot;United States&quot;] // or the user&#39;s country
        
    filteredLocations = allLocations.filter { $0.name.contains(searchText) }.sorted { a, b in
                switch (topCountries.contains(a.country), topCountries.contains(b.country)) {
                    case (true, false): return true
                    case (false, true): return false
                    default: return a.name &lt; b.name
                }
            }

huangapple
  • 本文由 发表于 2023年2月10日 03:58:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75403828.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定