0

I have the following code:

struct MyData {
    var company = String();
    var score:Int;
}

let data = [
    MyData(company: "smiths", score: 4 ),
    MyData(company: "lukes", score: 4),
    MyData(company: "lukes", score: 9)
]

extension MyData: CustomStringConvertible {
    var description: String {
        return "(\(company), \(score))"
    }
}

data.sorted { ($0.company, $1.score) < ($1.company, $0.score) }
print(data)

My output is:

[(smiths, 4), (lukes, 4), (lukes, 9)]

However, I want it to be the other way around:

[(lukes, 9), (lukes, 4), (smiths, 4)]

Can someone show me what it is I'm doing wrong?

3
  • 3
    So your sorting rule should be: 1) first sort alphabetically based on the company 2) if the company is the same, sort based on the score? By the way, you are printing your original array. sorted returns a new array containing the sorted results, it's not a mutating function. It couldn't even work with a mutating function, since data is immutable. Commented Sep 6, 2017 at 16:27
  • If the sort is reversed, change < to >. Commented Sep 6, 2017 at 16:30
  • @DávidPásztor Exactly. Commented Sep 6, 2017 at 16:31

3 Answers 3

3

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)
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I forgot to assign sorted data to a new variable.
1

Using the sorting rule described in comments, this is how your custom sorting function should look like:

let sorted = data.sorted(by: { this, next in
    if this.company < next.company {
        return true //first sort based on ascending company name
    } else if this.company == next.company {
        return this.score > next.score //if company name is the same, sort by descending score
    } else {
        return false //if company name is later in the alphabet, put it later in the sorted output
    }
})
print(sorted)

Output:

[(lukes, 9), (lukes, 4), (smiths, 4)]

Moreover, the code you used didn't work for two reasons: sorted returns a new array containing the sorted results, it's not a mutating function. It couldn't even work with a mutating function, since data is immutable.

Comments

0

So I discovered that my solution was almost there. Because the sorted function returns a new array, and doesn't actually sort the array it is being called on, my print statement was always printing the original collection. The solution to my problem was:

var myArray = data.sorted { ($0.company, $1.score) < ($1.company, $0.score) }
print(myArray)

Thanks very much for the help. :-)

Comments

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.