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
How to Make Async/Await in Swift
Firebase Connection Manager Should Return Only One Result
Automatically Increase/Decrease Uilabelview Height in Uitableviewcell
Type 'Any' Has No Subscript Members in Swift 3 Xcode 8
Sirikit, How to Display Response for Start Workout Intent
Adding Firebase Data to an Array in iOS Swift
Can't Dismiss Navigation Controller in Swift
The Meaning of "Withevent" in Swift, and Parameter Modifiers in General
Extract 4 Bits of Bluetooth Hex Data
Video Thumbnail Taking 10-15 Secs to Display
How to Draw a Simple Rounded Rect in Swift (Rounded Corners)
How to Reuse Struct on Swift? or Is There Any Other Way
iOS Firebase Database Get Key of Value
Wkwebview Is Showing Only Background
Firebase: Provided Bucket Does Not Match the Storage Bucket of the Current Instance in Swift
Generate a Hmac Swift Sdk8.3 Using Cchmac()
Swift Save Viewcontroller State Using Coder Beyond App Close