1

I have an NSTableView with an array datasource that I'm sorting when the user clicks on a column header. At the moment I have some IF statements to sort ascending/descending for every column name. Is it possible to perform a sort using a variable property name? That is, instead of hard coding .name in the following example, I could use a variable containing the name of the property instead of .name?

tableContents.sort {
    $0.name.localizedCaseInsensitiveCompare($1.name) == NSComparisonResult.OrderedAscending
}

This does work, but I have to duplicate this for every column in the table

1
  • consider to use an NSArrayController to get the sorting stuff for free Commented Aug 12, 2015 at 10:40

1 Answer 1

1

If all the properties that are used for sorting have the same type, you could use the built-in key-value access. Consider the following class A with two properties a and b both of which are strings.

class A: NSObject, Printable {
    var a: String
    var b: String

    init(a: String, b: String) {
        self.a = a
        self.b = b
    }

    override var description: String {
        return "{ a: \(self.a), b: \(self.b) }"
    }
}

Let's say your table contents are build from instances of this class.

var tableContents = [A(a: "1", b: "2"), A(a: "2", b: "1")]

To sort this array based on the values of either a or b you could use the following.

tableContents.sort {
    let key = "a"
    let oneValue = $0.valueForKey(key) as! String
    let otherValue = $1.valueForKey(key) as! String
    return oneValue.localizedCaseInsensitiveCompare(otherValue) == NSComparisonResult.OrderedAscending
}

println(tableContents) // [{ a: 1, b: 2 }, { a: 2, b: 1 }]

tableContents.sort {
    let key = "b"
    let oneValue = $0.valueForKey(key) as! String
    let otherValue = $1.valueForKey(key) as! String
    return oneValue.localizedCaseInsensitiveCompare(otherValue) == NSComparisonResult.OrderedAscending
}

println(tableContents) // [{ a: 2, b: 1 }, { a: 1, b: 2 }]

The only difference in the comparison block is the usage of either let key = "a" or let key = "b".

Sign up to request clarification or add additional context in comments.

1 Comment

My properties are not all of the same type, so I take your point. I'm probably asking the impossible. Your solution will probably still come in handy, though. Thanks.

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.