Skip to content

Instantly share code, notes, and snippets.

@charlieMonroe
Created July 31, 2016 09:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charlieMonroe/0752cd61f7937f714b689137daf9de21 to your computer and use it in GitHub Desktop.
Save charlieMonroe/0752cd61f7937f714b689137daf9de21 to your computer and use it in GitHub Desktop.
Sortable Properties

Sortable properties

Introduction

This proposal suggests introduction of a @sortable attribute that may be applied to properties.

Motivation

Sorting is quite a frequent task that is performed quite a lot. In order to maintain the sorting logic, often times it is convenient to create an extension on Sequence such as this one:

class Person {
	var age: Int = 21
	var firstName: String = "John"
	var lastName: String = "Doe"
}

extension Sequence where Self.Iterator.Element: MyClass {
	func sortedByFirstName() -> [Self.Iterator.Element] {
		return self.sorted(isOrderedBefore: { $0.firstName < $1.firstName })
	}
	func sortedByLastName() -> [Self.Iterator.Element] {
		return self.sorted(isOrderedBefore: { $0.lastName < $1.lastName })
	}
	func sortedByAge() -> [Self.Iterator.Element] {
		return self.sorted(isOrderedBefore: { $0.age < $1.age })
	}
}

This introduces a lot of boilerplate since a method needs to be implemented for each property by which one wants to define sorting.

Proposed solution

This proposal suggests adding a @sortable attribute that may be applied to a property that conforms to Comparable as follows:

class Person {
	@sortable
	var firstName: String = "John"
	
	@sortable
	var lastName: String = "Doe"
	
	@sortable
	var age: Int = 0
}

The compiler would then generate an extension on Sequence, which is composed as sorted<PropertyName>(ascending: Bool = true). The usage would look like this:

var people = [ 
	Person(firstName: "John", lastName: "Doe", age: 15), 
	Person(firstName: "Jane", lastName: "Doe", age: 20), 
]
people.sortByFirstName() // Jane Doe, John Doe
people.sortByAge() // John Doe, Jane Doe
people.sortByFirstName(ascending: false) // John Doe, Jane Doe

Future direction

This addition could in the future lead to a Swift-like sort descriptors to be used by Interface Builder.

Impact on existing code

None since this is purely additive.

Alternatives considered

  • Not implementing this at all.
  • Allow @sortable(ascending) and @sortable(descending) instead of a default ascending argument.
  • Instead of using ascending: Bool use ascending: SortDirection, where SortDirection is an enum with .ascending and .descending values.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment