Home > Enterprise >  Why am I being told city had no member .sort
Why am I being told city had no member .sort

Time:05-03

How do I fix this? I've tried different things

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{ $0.Population < $1.Population }
}

CodePudding user response:

There are a few issues here.

  1. You should conform to the Swift convention of capitalizing type names and using lowercase names for variables and properties. That will make this less confusing.

  2. Your CityArray doesn't use array syntax, which uses square brackets

  3. You don't use the List parameter you send in to your CityLists function.

It's unclear whether you want to sort in-place or return an array -- I've chosen the latter in my example:

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 { $0.population < $1.population }
}
                 
print(cityLists(list: cityArray))

If for some reason you wanted to sort in place (not recommended, as it's not very Swift-y). you could do:

func cityLists(list: inout [City]) {
    list.sort { $0.population < $1.population }
}
              
cityLists(list: &cityArray)

CodePudding user response:

You asked:

Why am I being told city had no member .sort

This is because the sort method (which does a “sort in place”) only works with a mutable array. But your sorting method has a list parameter, which is an immutable copy of your array.

So, consider the following (using standard name capitalization conventions):

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

You can either “sort in place” by making the parameter an inout, making the parameter mutable:

func sortByPopulation(_ array: inout [City]) {
    array.sort{ $0.population < $1.population }
}

sortByPopulation(cities)

Or you can write a function to return a new sorted array, leaving the original one “as is”:

func sortedByPopulation(_ array: [City]) -> [City] {
    return array.sorted { $0.population < $1.population }
}

let sortedCities = sortedByPopulation(cities)

A slightly more advanced idea might be to add a unique population sorting routines to arrays of cities:

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

Then you can do things like:

cities.sortByPopulation()

Or:

let sortedCities = cities.sortedByPopulation()

This leads to more natural reading code.


And, before someone complains about using an Array extension (which I did to keep it relatively simple), one probably might want to define these methods on broader purpose protocols, rather than only Array instances. E.g., one define sortedByPopulation to be an extension of Sequence, rather than Array:

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

This would support a broader array of scenarios. E.g., you can do things like sorting array slices:

let sorted = cities[2...].sortedByPopulation()

This is a slightly more flexible pattern, permitting sorting of any sequence of cities, not just arrays.

  • Related