1

I have an array of Users objects:

Class Users {
    var firstName:String!
    var lastName:String!
    var status:Int!

    override init(fn: String, ln: String, s: Int) {
        self.firstName = fn
        self.lastName = ln
        self.status = s
    }
}

var users:[Users] = [Users]()
users.append(Users(fn:"a", ln:"b", s:1))
users.append(Users(fn:"c", ln:"d", s:3))
users.append(Users(fn:"e", ln:"f", s:2))
users.append(Users(fn:"g", ln:"h", s:1))
users.append(Users(fn:"i", ln:"j", s:1))
users.append(Users(fn:"k", ln:"l", s:2))

I know the method to sort this array on status like

users = users.sorted(by: {$0.status > $1.status})

But, how could I sort users array on status with 2 on top then 3 and in the last 1 i.e [2,2,3,1,1,1]

6
  • Is your value of s fixed? that must be in 2 , 3 , 1 ? Commented Nov 27, 2017 at 13:54
  • 1
    what is the purpose of sorting the array if you want a specific order ? Commented Nov 27, 2017 at 13:56
  • @JonSnow I have random values of 's' i.e status Commented Nov 27, 2017 at 13:56
  • 2
    maybe you should define an enum that represents the status. Then you could assign an int value to each status type and order based on that value. Commented Nov 27, 2017 at 13:58
  • @marshallino16 2=online, 1=offline, 3=busy Commented Nov 27, 2017 at 13:58

3 Answers 3

3

Consider refactoring:

Class to struct:

struct User {
    var firstName:String!
    var lastName:String!
    var status:Status
}

Status enum:

enum Status: Int {
    case online, busy, offline
}

Population:

var users: [User] = [
    User(firstName: "a", lastName: "b", status: .online),
    User(firstName: "c", lastName: "d", status: .offline),
    User(firstName: "e", lastName: "f", status: .busy),
    User(firstName: "g", lastName: "h", status: .online),
    User(firstName: "i", lastName: "j", status: .online),
    User(firstName: "k", lastName: "l", status: .busy)
]

Sort:

users = users.sorted(by:{$0.status.rawValue < $1.status.rawValue })

users.forEach { print($0) }

Output:

User(firstName: a, lastName: b, status: .online)
User(firstName: g, lastName: h, status: .online)
User(firstName: i, lastName: j, status: .online)
User(firstName: e, lastName: f, status: .busy)
User(firstName: k, lastName: l, status: .busy)
User(firstName: c, lastName: d, status: .offline)
Sign up to request clarification or add additional context in comments.

Comments

1

Try this. This will sort based on the order array. If any status is missing will be moved to bottom of the array.

let order = [2,3,1]
users = users.sorted(by: { order.index(of: $0.status) ?? Int.max < order.index(of: $1.status) ?? Int.max })
// 2,2,3,1,1,1

Lets say if 3 is missing in order array

let order = [2,1]
users = users.sorted(by: { order.index(of: $0.status) ?? Int.max < order.index(of: $1.status) ?? Int.max })
// 2,2,1,1,1,3

1 Comment

Great! this is what I want. Thanks.
1

Use a lookup for your sort order.

let sortPriority: [Int: Int] = [ 1: 3, 2: 1, 3: 2]

Also you can use the mutating sort to sort the array in place instead of sorted which returns a copy since it looks like you are discarding the original array:

users.sort(by: {sortPriority [$0.status, default: Int.max] < sortPriority [$1.status, default: Int.max]})
print(users.flatMap{$0.status})

output:

[2, 2, 3, 1, 1, 1]

1 Comment

Thanks for your support, this solution is also fine I got it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.