为什么我被告知 city 没有成员 .sort

Why am I being told city had no member .sort

我该如何解决这个问题?我尝试过不同的东西

struct city {
    let name: String
    let county: String
    let State: String
    let Population: Int
}

let city1 = city(name: "Knoxville", county: "Knox", State: "Tennessee", Population: 186173)
let city2 = city(name: "Clarksville", county: "Montgomery", State: "Tennessee", Population: 152934)
let city3 = city(name: "Nashville", county: "Davidson", State: "Tennessee", Population: 692587)
let city4 = city(name: "Chattanooga", county: "Hamilton", State: "Tennessee", Population: 179690)
let city5 = city(name: "Memphis", county: "Shelby", State: "Tennessee", Population: 651932)

var CityArray = (city1, city2, city3, city4, city5)

func CityLists(List: [city]) {
    city.sort{ [=10=].Population < .Population }
}

这里有一些问题。

  1. 您应该遵守 Swift 类型名称大写和变量和属性名称小写的约定。这将使这不那么混乱。

  2. 你的CityArray没有使用数组语法,它使用方括号

  3. 您没有使用发送给 CityLists 函数的 List 参数。

不清楚您是想对数组进行排序 in-place 还是 return -- 我在示例中选择了后者:

struct City {
    var name: String
    var county: String
    var state: String
    var population: Int
}

let city1 = City(name: "Knoxville", county: "Knox", state: "Tennessee", population: 186173)
let city2 = City(name: "Clarksville", county: "Montgomery", state: "Tennessee", population: 152934)
let city3 = City(name: "Nashville", county: "Davidson", state: "Tennessee", population: 692587)
let city4 = City(name: "Chattanooga", county: "Hamilton", state: "Tennessee", population: 179690)
let city5 = City(name: "Memphis", county: "Shelby", state: "Tennessee", population: 651932)

var cityArray = [city1, city2, city3, city4, city5]

func cityLists(list: [City]) -> [City] {
    list.sorted { [=10=].population < .population }
}
                 
print(cityLists(list: cityArray))

如果出于某种原因您想就地排序(不推荐,因为它不是很 Swift-y)。你可以这样做:

func cityLists(list: inout [City]) {
    list.sort { [=11=].population < .population }
}
              
cityLists(list: &cityArray)

你问过:

Why am I being told city had no member .sort

这是因为:

  • CityArray不是一个数组,而是一个元组(因为你用的是圆括号而不是方括号);
  • CityLists 没有使用您传递给方法的参数;和
  • 即使您确实更改了 CityLists 以使用其参数,sort 方法(执行“就地排序”,对现有数组进行排序而不是 return新排序数组)仅适用于 mutable 集合;但是您的排序方法有一个列表参数,它是数组的 immutable 副本。

因此,请考虑以下内容(使用标准名称大写约定):

struct City {
    let name: String
    let county: String
    let state: String
    let population: Int
}

let city1 = City(name: "Knoxville", county: "Knox", state: "Tennessee", population: 186173)
let city2 = City(name: "Clarksville", county: "Montgomery", state: "Tennessee", population: 152934)
let city3 = City(name: "Nashville", county: "Davidson", state: "Tennessee", population: 692587)
let city4 = City(name: "Chattanooga", county: "Hamilton", state: "Tennessee", population: 179690)
let city5 = City(name: "Memphis", county: "Shelby", state: "Tennessee", population: 651932)

var cities = [city1, city2, city3, city4, city5] // note the square brackets, which make this an array, not parentheses, which would make it a tuple

您可以通过使参数成为 inout 来“就地排序”,使参数可变:

func sortByPopulation(_ array: inout [City]) {
    array.sort{ [=11=].population < .population }
}

sortByPopulation(&cities)

或者你可以写一个函数到 return 一个新的排序数组,让原来的数组“保持原样”:

func sortedByPopulation(_ array: [City]) -> [City] {
    return array.sorted { [=12=].population < .population }
}

let sortedCities = sortedByPopulation(cities)

一个稍微高级的想法可能是向城市数组添加人口排序例程:

extension Array where Element == City {
    mutating func sortByPopulation() {
        sort { [=13=].population < .population }
    }
    
    func sortedByPopulation() -> [City] {
        return sorted { [=13=].population < .population }
    }
}

然后你可以这样做:

cities.sortByPopulation()

或:

let sortedCities = cities.sortedByPopulation()

这样可以更自然地阅读代码。


并且,在有人抱怨使用 Array 扩展(我这样做是为了使其相对简单)之前,人们可能会在更广泛的目的协议上定义这些方法,而不仅仅是 Array 实例.例如:

extension MutableCollection where Self: RandomAccessCollection, Element == City {
    mutating func sortByPopulation() {
        sort { [=16=].population < .population }
    }
}

extension Sequence where Element == City {
    func sortedByPopulation() -> [City] {
        return sorted { [=16=].population < .population }
    }
}

这是一种稍微灵活一些的模式,允许对城市的任何序列或可变集合进行排序,而不仅仅是它们的数组。


如果你已经跟着我走了这么远,你可能想看看 Sundell 的 Sorting Swift collections 的 Swift 其他模式。

例如,我特别喜欢 keypath 通用模式:

extension MutableCollection where Self: RandomAccessCollection {
    mutating func sort<T: Comparable>(by keyPath: KeyPath<Element, T>) {
        sort { [=17=][keyPath: keyPath] < [keyPath: keyPath] }
    }
}

extension Sequence {
    func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>) -> [Element] {
        sorted { [=17=][keyPath: keyPath] < [keyPath: keyPath] }
    }
}

那么你可以这样做:

cities.sort(by: \.population)
let sorted = cities.sorted(by: \.population)