Sorting Struct Array in Swift 4

Sorting Struct array in Swift 4

Try below code, it sorts the struct in asc order but it pushes nil timestamps to bottom.
if you want nil timestamps to be at top, make all nil checks in below code to return opposite of what i return in below code.

var sortedArray = sessionsData?.items?.sorted(by: { (lhs, rhs) -> Bool in

if let lhsTime = lhs.startTime, let rhsTime = rhs.startTime {
return lhs.startTime < rhs.startTime
}

if lhs.startTime == nil && rhs.startTime == nil {
// return true to stay at top
return false
}

if lhs.startTime == nil {
// return true to stay at top
return false
}

if rhs.startTime == nil {
// return false to stay at top
return true
}

})

Swift. Sort array of struct

Your code works fine when you tested in a Playground in the following way:

struct SoundTrack {
let sID : Int
let st : String
}

var aSoundTracks_Filtered = [SoundTrack]()

aSoundTracks_Filtered.append(SoundTrack(sID: 1, st: "a"))
aSoundTracks_Filtered.append(SoundTrack(sID: 2, st: "b"))

aSoundTracks_Filtered.sort{ $0.st > $1.st } // [{sID 2, st "b"}, {sID 1, st "a"}]

But sort() sorts an array in-place. What you probably want to use is sorted(), which does not modify the original array and returns a new sorted array:

let aRes = aSoundTracks_Filtered.sorted{ $0.st > $1.st }

The above code is for Swift 1.2, for Swift 2.0 returning a sorted array is called "sort" again, but it is a (protocol extension) method now instead of a global function. I hope this help you.

How do you sort an array of structs in swift

Sort within the same array variable

Sort functions bellow are exactly the same, the only difference how short and expressive they are:

Full declaration:

myArr.sort { (lhs: EntryStruct, rhs: EntryStruct) -> Bool in
// you can have additional code here
return lhs.deadline < rhs.deadline
}

Shortened closure declaration:

myArr.sort { (lhs:EntryStruct, rhs:EntryStruct) in
return lhs.deadline < rhs.deadline
}
// ... or even:
myArr.sort { (lhs, rhs) in return lhs.deadline < rhs.deadline }

Compact closure declaration:

myArr.sort { $0.deadline < $1.deadline }

Sort to a new array variable

Full declaration:

let newArr = myArr.sorted { (lhs: EntryStruct, rhs: EntryStruct) -> Bool in
// you can have additional code here
return lhs.deadline < rhs.deadline
}

Shortened closure declaration:

let newArr = myArr.sorted { (lhs:EntryStruct, rhs:EntryStruct) in
return lhs.deadline < rhs.deadline
}
// ... or even:
let newArr = myArr.sorted { (lhs, rhs) in return lhs.deadline < rhs.deadline }

Compact closure declaration:

let newArr = myArr.sorted { $0.deadline < $1.deadline }

sort struct in alphabetical order (swift4)

If your goal is to sort your array of Person objects then sort contacts:

@IBAction func save(_ sender: Any) {
contacts.append(Person(name: a.text!))
contacts.sort { $0.name < $1.name }
label.text = contacts.map { $0.description }.joined(separator: "\n")
}

And as mentioned in the comments, you should update your Person struct:

struct Person: CustomStringConvertible {
let name: String

var description: String {
return name
}
}

Need help sorting a Struct by Timestamp in Swift

Suggest you to change structure of your model:

struct TripDetails {
struct LocationInfo {
var location: GeoPoint
var timestamp: TimeStamp
}

let tripDepartureTime: String
var locations: [LocationInfo]

}

Sorting:

var tripDetails = ... // Getting model
tripDetails.locations.sort(by: { $0.timestamp.seconds > $1.timestamp.seconds })

Sorting an array of struct objects using two parameters in Swift

You want to sort by company ascending then by score descending.

First of all – as mentioned in the comments – you have to assign the result to a new variable, print(data) prints the unsorted original array.

The sort algorithm is supposed to be

if the companies are equal sort the scores descending otherwise sort the companies ascending

let sortedData = data.sorted { ($0.company == $1.company) ? $0.score > $1.score : $0.company < $1.company}
print(sortedData)

Swift sorted(by:) method doesn't correctly sort an array of struct based on integer

The predicate to Array.sorted(by:) requires that you

return true if its first argument should be ordered before its second argument; otherwise, false.

The order of the arguments passed to the predicate can be given in either order ((a, b) or (b, a)) depending on how the list has been sorted so far, but the predicate must give a consistent result in either order or else you'll get nonsense results.

In your predicate, you're checking the first element's user ID to prioritize it, but not the second; i.e., you're handling (a, b) but not (b, a). If you update your predicate to

myArray.sorted(by: {
// The order of the checking here matters. Specifically, the predicate
// requires a `<` relationship, not a `<=` relationship. If both $0 and $1
// have the same `user_id`, we need to return `false`. Checking $1.user_id
// first hits two birds with one stone.
if $1.user_id == 40 {
return false
} else if $0.user_id == 40 {
return true
}

return $0.user_id < $1.user_id
})

then you'll get consistent results.

Alternatively, if the element is known ahead of time, you can avoid this by extracting it from the list and sorting the remaining results.



Related Topics



Leave a reply



Submit