├── Pod ├── Assets │ └── .gitkeep └── Classes │ ├── NSSortDescriptor+CompareFunction.swift │ ├── Sequence+SortedByComparing.swift │ └── CompareFunctions.swift ├── _Pods.xcodeproj ├── Example ├── Podfile ├── SwiftSortUtils.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── SwiftSortUtils-Example.xcscheme │ └── project.pbxproj ├── SwiftSortUtils.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Podfile.lock ├── SwiftSortUtilsTests │ ├── Info.plist │ └── SwiftSortUtilsTests.swift └── Tests │ └── Info.plist ├── Package.swift ├── .travis.yml ├── .gitignore ├── LICENSE ├── SwiftSortUtils.podspec └── README.md /Pod/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | use_frameworks! 3 | 4 | platform :ios, '9.0' 5 | 6 | target 'SwiftSortUtilsTests' do 7 | pod "SwiftSortUtils", :path => "../" 8 | end 9 | -------------------------------------------------------------------------------- /Example/SwiftSortUtils.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/SwiftSortUtils.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/SwiftSortUtils.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SwiftSortUtils (0.4.0) 3 | 4 | DEPENDENCIES: 5 | - SwiftSortUtils (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SwiftSortUtils: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | SwiftSortUtils: a155c1aaf029348c058bab90509e9cedbe72c40c 13 | 14 | PODFILE CHECKSUM: f782d16a7b742530805b5d278933c4d7f425cf56 15 | 16 | COCOAPODS: 1.10.1 17 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "SwiftSortUtils", 7 | products: [ 8 | .library(name: "SwiftSortUtils", targets: ["SwiftSortUtils"]), 9 | ], 10 | targets: [ 11 | .target( 12 | name: "SwiftSortUtils", 13 | path: "Pod/Classes" 14 | ) 15 | ], 16 | swiftLanguageVersions: [.v5] 17 | ) 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | language: objective-c 6 | osx_image: xcode8.3 7 | cache: cocoapods 8 | podfile: Example/Podfile 9 | 10 | before_install: 11 | - gem install cocoapods # Since Travis is not always on latest version 12 | # - pod install --project-directory=Example 13 | 14 | install: 15 | - gem install xcpretty --no-rdoc --no-ri --no-document --quiet 16 | 17 | script: 18 | # - set -o pipefail && xcodebuild test -workspace Example/SwiftSortUtils.xcworkspace -scheme SwiftSortUtils -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO 19 | - pod --version 20 | - pod lib lint --verbose 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | .build 22 | 23 | Example/Pods 24 | 25 | # Bundler 26 | .bundle 27 | 28 | Carthage 29 | # We recommend against adding the Pods directory to your .gitignore. However 30 | # you should judge for yourself, the pros and cons are mentioned at: 31 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 32 | # 33 | # Note: if you ignore the Pods directory, make sure to uncomment 34 | # `pod install` in .travis.yml 35 | # 36 | # Pods/ 37 | -------------------------------------------------------------------------------- /Example/SwiftSortUtilsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.cocoapods.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Daniel Strittmatter 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pod/Classes/NSSortDescriptor+CompareFunction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSSortDescriptor+CompareFunction.swift 3 | // Pods 4 | // 5 | // Created by Daniel Strittmatter on 06/10/15. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | public extension NSSortDescriptor { 12 | 13 | /** 14 | Generates a compare function (suitable for Swift Arrays' sort methods) 15 | from a NSSortDescriptor. 16 | 17 | - returns: the generate compare function 18 | */ 19 | func toCompareFunction() -> ((T, T) -> Bool) { 20 | return { (a, b) in 21 | self.compare(a, to: b) == ComparisonResult.orderedAscending 22 | } 23 | } 24 | 25 | } 26 | 27 | public extension Sequence where Self.Iterator.Element == NSSortDescriptor { 28 | 29 | /** 30 | Generates a compare function (suitable for Swift Arrays' sort methods) 31 | from a list of NSSortDescriptors 32 | 33 | - returns: the generated compare function 34 | */ 35 | func toCompareFunction() -> ((T, T) -> Bool) { 36 | let compareFunctions: [(T, T) -> Bool] = map { $0.toCompareFunction() } 37 | return compareFunctions.reduce(identityCompareFunction(), combineCompareFunctions) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /SwiftSortUtils.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint SwiftSortUtils.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = "SwiftSortUtils" 11 | s.version = "0.5.0" 12 | s.summary = "Useful functions and extensions for sorting in Swift" 13 | 14 | s.description = <<-DESC 15 | This library takes a shot at making sorting in Swift more pleasant. 16 | It also allows you to reuse your old NSSortDescriptor instances in Swift. 17 | DESC 18 | 19 | s.homepage = "https://github.com/dsmatter/SwiftSortUtils" 20 | s.license = 'MIT' 21 | s.author = { "Daniel Strittmatter" => "daniel@smattr.de" } 22 | s.source = { :git => "https://github.com/dsmatter/SwiftSortUtils.git", :tag => s.version.to_s } 23 | 24 | s.platform = :ios, '9.0' 25 | s.swift_version = '5.0' 26 | s.requires_arc = true 27 | 28 | s.source_files = 'Pod/Classes/**/*' 29 | end 30 | -------------------------------------------------------------------------------- /Pod/Classes/Sequence+SortedByComparing.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Sequence+SortedByComparing.swift 3 | // SwiftSortUtils 4 | // 5 | // Created by Daniel on 28.10.21. 6 | // 7 | 8 | import Foundation 9 | 10 | public extension Sequence { 11 | /** 12 | Returns the elements of the sequence, sorted using the given transformation function `f`. 13 | 14 | Elements are compared by the results of applying the transformation function. 15 | Calling this method with ascending order is equivalent to: `sorted(by: { f($0) < f($1) })`. 16 | 17 | - parameter byComparing: the transformation function 18 | - parameter ordering: the ordering (ascending or descending) 19 | 20 | - returns: a sorted array of the sequence's elements. 21 | */ 22 | func sorted(byComparing f: (Element) -> C, ordering: Ordering = .ascending) -> [Element] { 23 | // Re-using the `compareBy` function would require an escaping closure. 24 | switch ordering { 25 | case .ascending: 26 | return sorted(by: { f($0) < f($1) }) 27 | case .descending: 28 | return sorted(by: { f($0) > f($1) }) 29 | } 30 | } 31 | 32 | /** 33 | Returns the elements of the sequence, sorted using the given transformation functions `fs`. 34 | 35 | Elements are compared by applying the transformation functions in descending priority. 36 | The compare function used for sorting is equivalent to: `compareBy(ordering, fs)`. 37 | 38 | - parameter byComparing: the transformation functions 39 | - parameter ordering: the ordering (ascending or descending) 40 | 41 | - returns: a sorted array of the sequence's elements. 42 | */ 43 | func sorted(byComparing fs: [(Element) -> C], ordering: Ordering = .ascending) -> [Element] { 44 | return sorted(by: compareBy(ordering, fs)) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftSortUtils 2 | 3 | [![CI Status](https://img.shields.io/travis/dsmatter/SwiftSortUtils.svg?style=flat)](https://travis-ci.org/dsmatter/SwiftSortUtils.svg?branch=master) 4 | [![Version](https://img.shields.io/cocoapods/v/SwiftSortUtils.svg?style=flat)](http://cocoapods.org/pods/SwiftSortUtils) 5 | [![License](https://img.shields.io/cocoapods/l/SwiftSortUtils.svg?style=flat)](http://cocoapods.org/pods/SwiftSortUtils) 6 | [![Platform](https://img.shields.io/cocoapods/p/SwiftSortUtils.svg?style=flat)](http://cocoapods.org/pods/SwiftSortUtils) 7 | 8 | ## Motivation 9 | 10 | This library takes a shot at making comparing and sorting in Swift more pleasant. It also allows you to reuse your old `NSSortDescriptor` instances in Swift. 11 | 12 | ## Examples 13 | 14 | ```swift 15 | let somePeople: [Person] = ... 16 | 17 | // Sort by a single comparable attribute 18 | let ... = somePeople.sort(by: compareBy(\.firstname)) 19 | let ... = somePeople.sort(by: compareBy { $0.firstname }) 20 | let ... = somePeople.sort(by: compareBy(.descending, \.firstname)) 21 | let ... = somePeople.sort(byComparing: \.firstname) 22 | let ... = somePeople.sort(byComparing: \.firstname, ordering: .descending) 23 | 24 | // Sort by multiple attributes 25 | let ... = somePeople.sort(by: 26 | compareBy { $0.age } <|> 27 | compareBy { $0.lastname } <|> 28 | compareBy(\.firstname) 29 | ) 30 | 31 | // With less cumbersome syntax: 32 | let ... = somePeople.sort(by: \.age <|> \.firstname <|> \.lastname) 33 | let ... = somePeople.sort(byComparing: [\.firstname, \.lastname]) // monomorphic 34 | 35 | // Append any comparator function 36 | let ... = somePeople.sort(by: 37 | compareBy { $0.age } <|> 38 | { (p1, p2) in p1.wearsGlasses() && !p2.wearsGlasses() } 39 | ) 40 | 41 | // Reverse compare functions 42 | let ... = somePeople.sort(by: 43 | compareBy(.descending) { $0.age } <|> 44 | compareBy { $0.lastname } <|> 45 | reverseComparator(compareBy(\.firstname)) // reverse any compare function 46 | ) 47 | 48 | // Mix and match extractor and compare functions: 49 | let ... = somePeople.sort(by: 50 | compareBy(.descending, \.age) <|> 51 | \.firstname <|> 52 | \.lastname <|> 53 | reverseComparator(myCompareFunction) 54 | ) 55 | 56 | // Use an NSSortDescriptor 57 | let ageSortDescriptor = NSSortDescriptor(key: "age", ascending: true) 58 | let ... = somePeople.sort(ageSortDescriptor.toCompareFunction()) 59 | 60 | // Even Use multiple NSSortDescriptors 61 | let nameSortDescriptors = [ 62 | NSSortDescriptor(key: "lastname", ascending: true), 63 | NSSortDescriptor(key: "firstname", ascending: true) 64 | ] 65 | let ... = somePeople.sort(by: nameSortDescriptors.toCompareFunction()) 66 | ``` 67 | 68 | See the tests for more examples. 69 | 70 | ## Usage 71 | 72 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 73 | 74 | ## Installation 75 | 76 | ### Swift Version 77 | 78 | This Version of SwiftSortUtils is meant to be used with Swift 5. 79 | 80 | ### CocoaPods 81 | 82 | SwiftSortUtils is available through [CocoaPods](http://cocoapods.org). To install 83 | it, simply add the following line to your Podfile: 84 | 85 | ```ruby 86 | pod "SwiftSortUtils" 87 | ``` 88 | 89 | ### Manually 90 | 91 | Download the files in [`Pod/Classes`](https://github.com/dsmatter/SwiftSortUtils/tree/master/Pod/Classes) and drop them into your project. 92 | 93 | ## Author 94 | 95 | Daniel Strittmatter, daniel@smattr.de 96 | 97 | ## License 98 | 99 | SwiftSortUtils is available under the MIT license. See the LICENSE file for more info. 100 | -------------------------------------------------------------------------------- /Example/SwiftSortUtils.xcodeproj/xcshareddata/xcschemes/SwiftSortUtils-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 78 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Example/SwiftSortUtilsTests/SwiftSortUtilsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tests.swift 3 | // Pods 4 | // 5 | // Created by Daniel Strittmatter on 06/10/15. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | import UIKit 12 | import XCTest 13 | import SwiftSortUtils 14 | 15 | struct Point: Equatable { 16 | var x: Int 17 | var y: Int 18 | } 19 | 20 | func ==(lhs: Point, rhs: Point) -> Bool { 21 | return lhs.x == rhs.x && lhs.y == rhs.y 22 | } 23 | 24 | class FullName: NSObject { 25 | @objc var firstName: String 26 | @objc var lastName: String 27 | 28 | required init(firstName: String, lastName: String) { 29 | self.firstName = firstName 30 | self.lastName = lastName 31 | } 32 | } 33 | 34 | class Tests: XCTestCase { 35 | 36 | // MARK: Tests 37 | 38 | func testCombinedComparatorFunctions() { 39 | let testArray = (0..<1000).map { _ in randomPoint() } 40 | let testee = testArray.sorted(by: compareBy { $0.x } <|> compareBy{ $0.y }) 41 | assertSorted(points: testee, ordering: .ascending) 42 | } 43 | 44 | func testCombinedReversedComparatorFunctions() { 45 | let testArray = (0..<1000).map { _ in randomPoint() } 46 | let testee = testArray.sorted(by: compareBy(.descending) { $0.x } <|> compareBy(.descending) { $0.y }) 47 | assertSorted(points: testee, ordering: .descending) 48 | } 49 | 50 | func testCombinedArrayComparator() { 51 | let testArray = (0..<1000).map { _ in randomPoint() } 52 | let testee = testArray.sorted(by: compareBy([{ $0.x }, { $0.y }])) 53 | assertSorted(points: testee, ordering: .ascending) 54 | } 55 | 56 | func testCombinedKeyPaths() { 57 | let testArray = (0..<1000).map { _ in randomPoint() } 58 | let testee = testArray.sorted(by: compareBy([\.x, \.y])) 59 | assertSorted(points: testee, ordering: .ascending) 60 | } 61 | 62 | func testCombinedKeyPathsReversed() { 63 | let testArray = (0..<1000).map { _ in randomPoint() } 64 | let testee = testArray.sorted(by: compareBy(.descending, [\.x, \.y])) 65 | assertSorted(points: testee, ordering: .descending) 66 | } 67 | 68 | func testTransformerChain() { 69 | let testArray = (0..<1000).map { _ in randomPoint() } 70 | let testee = testArray.sorted(by: \.x <|> \.y <|> \.x) 71 | assertSorted(points: testee, ordering: .ascending) 72 | } 73 | 74 | func testMixedSyntax() { 75 | let testArray = (0..<1000).map { _ in randomPoint() } 76 | let testee = testArray.sorted( 77 | by: compareBy(.ascending, \.x) <|> \.y <|> reverseComparator(compareBy(.descending, { $0.x })) 78 | ) 79 | assertSorted(points: testee, ordering: .ascending) 80 | } 81 | 82 | func testSortByComparing() { 83 | let testArray = (0..<1000).map { _ in randomPoint() } 84 | let testee = testArray.sorted(byComparing: [\.x, \.y]) 85 | assertSorted(points: testee, ordering: .ascending) 86 | } 87 | 88 | func testSortByComparingReversed() { 89 | let testArray = (0..<1000).map { _ in randomPoint() } 90 | let testee = testArray.sorted(byComparing: [\.x, \.y], ordering: .descending) 91 | assertSorted(points: testee, ordering: .descending) 92 | } 93 | 94 | func testSortByComparingSingle() { 95 | let testArray = (0..<1000).map { _ in randomPoint() } 96 | let testee = testArray.sorted(byComparing: \.x) 97 | XCTAssertEqual(testee, testArray.sorted(by: { $0.x < $1.x })) 98 | } 99 | 100 | func testSortByComparingSingleReversed() { 101 | let testArray = (0..<1000).map { _ in randomPoint() } 102 | let testee = testArray.sorted(byComparing: \.y, ordering: .descending) 103 | XCTAssertEqual(testee, testArray.sorted(by: { $0.y > $1.y })) 104 | } 105 | 106 | func testSortDescriptorCompareFunction() { 107 | let testArray = (0..<1000).map { _ in randomName() } 108 | 109 | let sortDescriptor1 = NSSortDescriptor(key: "lastName", ascending: true) 110 | let sortDescriptor2 = NSSortDescriptor(key: "firstName", ascending: true) 111 | let sortDescriptors = [sortDescriptor1, sortDescriptor2] 112 | 113 | let testee = testArray.sorted(by: sortDescriptors.toCompareFunction()) 114 | let expected = (testArray as NSArray).sortedArray(using: sortDescriptors) as! [FullName] 115 | 116 | for i in 0..= b.x) 139 | if (a.x == b.x) { 140 | XCTAssert(a.y >= b.y) 141 | } 142 | } 143 | } 144 | } 145 | 146 | // MARK: Random Generation 147 | 148 | func randomPoint() -> Point { 149 | let x = Int(arc4random_uniform(100)) 150 | let y = Int(arc4random_uniform(100)) 151 | return Point(x: x, y: y) 152 | } 153 | 154 | func randomStringWithLength (_ len : Int) -> String { 155 | let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 156 | let randomString : NSMutableString = NSMutableString(capacity: len) 157 | 158 | for _ in 0 ..< len { 159 | let length = UInt32 (letters.length) 160 | let rand = arc4random_uniform(length) 161 | randomString.appendFormat("%C", letters.character(at: Int(rand))) 162 | } 163 | 164 | return randomString as String 165 | } 166 | 167 | func randomName() -> FullName { 168 | let firstName = randomStringWithLength(10) 169 | let lastName = randomStringWithLength(10) 170 | 171 | return FullName(firstName: firstName, lastName: lastName) 172 | } 173 | 174 | 175 | } 176 | -------------------------------------------------------------------------------- /Pod/Classes/CompareFunctions.swift: -------------------------------------------------------------------------------- 1 | /** 2 | Combines two compare functions into a new compare function, such that 3 | the first function is used as the first-order comparison and the second 4 | function as second-order comparison. 5 | 6 | - parameter f: first-order compare function 7 | - parameter g: second-order compare function 8 | 9 | - returns: composed compare function 10 | */ 11 | public func combineCompareFunctions(_ f: @escaping (T, T) -> Bool, _ g: @escaping (T, T) -> Bool) -> ((T, T) -> Bool) { 12 | return { (a, b) in 13 | let isLesser = f(a, b) 14 | if isLesser { 15 | return true 16 | } 17 | 18 | let isGreater = f(b, a) 19 | if isGreater { 20 | return false 21 | } 22 | 23 | return g(a, b) 24 | } 25 | } 26 | 27 | /** 28 | * Infix operator for combineCompareFunctions 29 | */ 30 | precedencegroup CompareFunctionCompositionPrecedence { 31 | lowerThan: AssignmentPrecedence 32 | associativity: left 33 | } 34 | infix operator <|>: CompareFunctionCompositionPrecedence 35 | 36 | public func <|>( 37 | f: @escaping (T, T) -> Bool, 38 | g: @escaping (T, T) -> Bool 39 | ) -> ((T, T) -> Bool) { 40 | return combineCompareFunctions(f, g) 41 | } 42 | 43 | public func <|>( 44 | _ cf: @escaping (T, T) -> Bool, 45 | _ f: @escaping (T) -> C 46 | ) -> ((T, T) -> Bool) { 47 | return cf <|> compareBy(f) 48 | } 49 | 50 | public func <|>( 51 | _ f: @escaping (T) -> C1, 52 | _ g: @escaping (T) -> C2 53 | ) -> ((T, T) -> Bool) { 54 | return compareBy(f) <|> g 55 | } 56 | 57 | /** 58 | Generates a compare function (suitable for Swift Arrays' sort methods) 59 | using the provided transformation function `f`. 60 | 61 | The resulting compare function compares elements by applying `f` and comparing the results: 62 | `{ a, b in f(a) < f(b) }` 63 | 64 | If the ordering parameter indicates a descending order the resulting 65 | compare function is reversed. 66 | 67 | - parameter ordering: the desired element ordering 68 | - parameter f: the transformation function 69 | 70 | - returns: the generated compare function 71 | */ 72 | public func compareBy(_ ordering: Ordering, _ f: @escaping (T) -> C) -> ((T, T) -> Bool) { 73 | switch ordering { 74 | case .ascending: 75 | return compareBy(f) 76 | case .descending: 77 | return reverseComparator(compareBy(f)) 78 | } 79 | } 80 | 81 | /** 82 | Generates a compare function (suitable for Swift Arrays' sort methods) 83 | using the provided transformation function `f`. 84 | 85 | The resulting compare function compares elements by applying `f` and comparing the results: 86 | `{ a, b in f(a) < f(b) }` 87 | 88 | - parameter f: the transformation function 89 | 90 | - returns: the generated compare function 91 | */ 92 | public func compareBy(_ f: @escaping (T) -> C) -> ((T, T) -> Bool) { 93 | return { a, b in f(a) < f(b) } 94 | } 95 | 96 | /** 97 | Generates a compare function (suitable for Swift Arrays' sort methods) 98 | using the provided transformation functions fs. 99 | 100 | The resulting compare function compares elements using the transformation functions in descending priority. 101 | 102 | Example: 103 | Let fs = [f1, f2, ..., f9]. The resulting compare function is equivalent to: f1 <|> f2 <|> ... <|> f9. 104 | 105 | If the ordering parameter indicates a descending order the resulting 106 | compare function is reversed. 107 | 108 | - parameter ordering: the desired element ordering 109 | - parameter fs: the transformation functions 110 | 111 | - returns: the generated compare function 112 | */ 113 | public func compareBy(_ ordering: Ordering, _ fs: [(T) -> C]) -> ((T, T) -> Bool) { 114 | return fs.reduce(identityCompareFunction()) { cmp, f in cmp <|> compareBy(ordering, f) } 115 | } 116 | 117 | /** 118 | Generates a compare function (suitable for Swift Arrays' sort methods) 119 | using the provided transformation functions fs. 120 | 121 | The resulting compare function compares elements using the transformation functions in descending priority. 122 | 123 | Example: 124 | Let fs = [f1, f2, ..., f9]. The resulting compare function is equivalent to: f1 <|> f2 <|> ... <|> f9. 125 | 126 | - parameter fs: the transformation functions 127 | 128 | - returns: the generated compare function 129 | */ 130 | public func compareBy(_ fs: [(T) -> C]) -> ((T, T) -> Bool) { 131 | return fs.reduce(identityCompareFunction()) { cmp, f in cmp <|> compareBy(f) } 132 | } 133 | 134 | /** 135 | Reverses a given compare function. 136 | 137 | - parameter f: the compare function 138 | 139 | - returns: the reversed compare function 140 | */ 141 | public func reverseComparator(_ f: @escaping (T, T) -> Bool) -> (T, T) -> Bool { 142 | return { (a, b) in 143 | f(b, a) 144 | } 145 | } 146 | 147 | /** 148 | The identity element in the monoid of compare functions. 149 | It always returns false, i.e. treats all elements as equal. 150 | 151 | - returns: the compare function identity 152 | */ 153 | func identityCompareFunction() -> ((T, T) -> Bool) { 154 | return { a, b in false } 155 | } 156 | 157 | public enum Ordering { 158 | case ascending 159 | case descending 160 | } 161 | 162 | // MARK: - Deprecated Functions 163 | 164 | /** 165 | Generates a compare function (suitable for Swift Arrays' sort methods) 166 | using the provided transformation function f. 167 | Elements are sorted by the result of applying each element to f. 168 | 169 | If the ordering parameter indicates a descending order the resulting 170 | compare function is reversed. 171 | 172 | - parameter ordering: the desired element ordering 173 | - parameter f: the transformation function 174 | 175 | - returns: the generated compare function 176 | */ 177 | @available(*, deprecated, renamed: "compareBy") 178 | public func sortingBy(_ ordering: Ordering, f: @escaping (T) -> C) -> ((T, T) -> Bool) { 179 | switch ordering { 180 | case .ascending: 181 | return sortingBy(f) 182 | case .descending: 183 | return reverseComparator(sortingBy(f)) 184 | } 185 | } 186 | 187 | /** 188 | Generates a compare function (suitable for Swift Arrays' sort methods) 189 | using the provided transformation function f. Elements are sorted by 190 | the result of applying each element to f. 191 | 192 | - parameter f: the transformation function 193 | 194 | - returns: the generated compare function 195 | */ 196 | @available(*, deprecated, renamed: "compareBy") 197 | public func sortingBy(_ f: @escaping (T) -> C) -> ((T, T) -> Bool) { 198 | return { a, b in 199 | f(a) < f(b) 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /Example/SwiftSortUtils.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1D89EAEDC7D9E8484FFCABAD /* Pods_SwiftSortUtilsTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 305BD5107F9ED03016F92FAE /* Pods_SwiftSortUtilsTests.framework */; }; 11 | 678304861DCF72DB0037C44F /* SwiftSortUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678304851DCF72DB0037C44F /* SwiftSortUtilsTests.swift */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXFileReference section */ 15 | 305BD5107F9ED03016F92FAE /* Pods_SwiftSortUtilsTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftSortUtilsTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 16 | 317EA0D0AF8482D2E3F774F9 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 17 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 18 | 678304831DCF72DB0037C44F /* SwiftSortUtilsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftSortUtilsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | 678304851DCF72DB0037C44F /* SwiftSortUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftSortUtilsTests.swift; sourceTree = ""; }; 20 | 678304871DCF72DB0037C44F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 21 | 7F428392DC369563D2A6A244 /* Pods-SwiftSortUtilsTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftSortUtilsTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftSortUtilsTests/Pods-SwiftSortUtilsTests.release.xcconfig"; sourceTree = ""; }; 22 | D12A97782F25D8B648886146 /* Pods-SwiftSortUtilsTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftSortUtilsTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftSortUtilsTests/Pods-SwiftSortUtilsTests.debug.xcconfig"; sourceTree = ""; }; 23 | D7DEDC59CC3C092CEAA567C1 /* SwiftSortUtils.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = SwiftSortUtils.podspec; path = ../SwiftSortUtils.podspec; sourceTree = ""; }; 24 | DE25A2102EE554CE7989A950 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 25 | /* End PBXFileReference section */ 26 | 27 | /* Begin PBXFrameworksBuildPhase section */ 28 | 678304801DCF72DB0037C44F /* Frameworks */ = { 29 | isa = PBXFrameworksBuildPhase; 30 | buildActionMask = 2147483647; 31 | files = ( 32 | 1D89EAEDC7D9E8484FFCABAD /* Pods_SwiftSortUtilsTests.framework in Frameworks */, 33 | ); 34 | runOnlyForDeploymentPostprocessing = 0; 35 | }; 36 | /* End PBXFrameworksBuildPhase section */ 37 | 38 | /* Begin PBXGroup section */ 39 | 2989E1BDAC50E1B7D0C65FAE /* Pods */ = { 40 | isa = PBXGroup; 41 | children = ( 42 | D12A97782F25D8B648886146 /* Pods-SwiftSortUtilsTests.debug.xcconfig */, 43 | 7F428392DC369563D2A6A244 /* Pods-SwiftSortUtilsTests.release.xcconfig */, 44 | ); 45 | name = Pods; 46 | sourceTree = ""; 47 | }; 48 | 476FCDE09C61C10985120F8C /* Frameworks */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 305BD5107F9ED03016F92FAE /* Pods_SwiftSortUtilsTests.framework */, 52 | ); 53 | name = Frameworks; 54 | sourceTree = ""; 55 | }; 56 | 607FACC71AFB9204008FA782 = { 57 | isa = PBXGroup; 58 | children = ( 59 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 60 | 607FACE81AFB9204008FA782 /* Tests */, 61 | 678304841DCF72DB0037C44F /* SwiftSortUtilsTests */, 62 | 607FACD11AFB9204008FA782 /* Products */, 63 | 2989E1BDAC50E1B7D0C65FAE /* Pods */, 64 | 476FCDE09C61C10985120F8C /* Frameworks */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | 607FACD11AFB9204008FA782 /* Products */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 678304831DCF72DB0037C44F /* SwiftSortUtilsTests.xctest */, 72 | ); 73 | name = Products; 74 | sourceTree = ""; 75 | }; 76 | 607FACE81AFB9204008FA782 /* Tests */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 607FACE91AFB9204008FA782 /* Supporting Files */, 80 | ); 81 | path = Tests; 82 | sourceTree = ""; 83 | }; 84 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 607FACEA1AFB9204008FA782 /* Info.plist */, 88 | ); 89 | name = "Supporting Files"; 90 | sourceTree = ""; 91 | }; 92 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | D7DEDC59CC3C092CEAA567C1 /* SwiftSortUtils.podspec */, 96 | 317EA0D0AF8482D2E3F774F9 /* README.md */, 97 | DE25A2102EE554CE7989A950 /* LICENSE */, 98 | ); 99 | name = "Podspec Metadata"; 100 | sourceTree = ""; 101 | }; 102 | 678304841DCF72DB0037C44F /* SwiftSortUtilsTests */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 678304851DCF72DB0037C44F /* SwiftSortUtilsTests.swift */, 106 | 678304871DCF72DB0037C44F /* Info.plist */, 107 | ); 108 | path = SwiftSortUtilsTests; 109 | sourceTree = ""; 110 | }; 111 | /* End PBXGroup section */ 112 | 113 | /* Begin PBXNativeTarget section */ 114 | 678304821DCF72DB0037C44F /* SwiftSortUtilsTests */ = { 115 | isa = PBXNativeTarget; 116 | buildConfigurationList = 6783048A1DCF72DB0037C44F /* Build configuration list for PBXNativeTarget "SwiftSortUtilsTests" */; 117 | buildPhases = ( 118 | 2C819F41414925F4A7C3DCD8 /* [CP] Check Pods Manifest.lock */, 119 | 6783047F1DCF72DB0037C44F /* Sources */, 120 | 678304801DCF72DB0037C44F /* Frameworks */, 121 | 678304811DCF72DB0037C44F /* Resources */, 122 | 2E36FF6F006116F848263CE0 /* [CP] Embed Pods Frameworks */, 123 | ); 124 | buildRules = ( 125 | ); 126 | dependencies = ( 127 | ); 128 | name = SwiftSortUtilsTests; 129 | productName = SwiftSortUtilsTests; 130 | productReference = 678304831DCF72DB0037C44F /* SwiftSortUtilsTests.xctest */; 131 | productType = "com.apple.product-type.bundle.unit-test"; 132 | }; 133 | /* End PBXNativeTarget section */ 134 | 135 | /* Begin PBXProject section */ 136 | 607FACC81AFB9204008FA782 /* Project object */ = { 137 | isa = PBXProject; 138 | attributes = { 139 | LastSwiftUpdateCheck = 0810; 140 | LastUpgradeCheck = 1310; 141 | ORGANIZATIONNAME = CocoaPods; 142 | TargetAttributes = { 143 | 678304821DCF72DB0037C44F = { 144 | CreatedOnToolsVersion = 8.1; 145 | DevelopmentTeam = G7C8M95922; 146 | LastSwiftMigration = 0810; 147 | ProvisioningStyle = Automatic; 148 | }; 149 | }; 150 | }; 151 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "SwiftSortUtils" */; 152 | compatibilityVersion = "Xcode 3.2"; 153 | developmentRegion = English; 154 | hasScannedForEncodings = 0; 155 | knownRegions = ( 156 | English, 157 | en, 158 | Base, 159 | ); 160 | mainGroup = 607FACC71AFB9204008FA782; 161 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 162 | projectDirPath = ""; 163 | projectRoot = ""; 164 | targets = ( 165 | 678304821DCF72DB0037C44F /* SwiftSortUtilsTests */, 166 | ); 167 | }; 168 | /* End PBXProject section */ 169 | 170 | /* Begin PBXResourcesBuildPhase section */ 171 | 678304811DCF72DB0037C44F /* Resources */ = { 172 | isa = PBXResourcesBuildPhase; 173 | buildActionMask = 2147483647; 174 | files = ( 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXResourcesBuildPhase section */ 179 | 180 | /* Begin PBXShellScriptBuildPhase section */ 181 | 2C819F41414925F4A7C3DCD8 /* [CP] Check Pods Manifest.lock */ = { 182 | isa = PBXShellScriptBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | ); 186 | inputPaths = ( 187 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 188 | "${PODS_ROOT}/Manifest.lock", 189 | ); 190 | name = "[CP] Check Pods Manifest.lock"; 191 | outputPaths = ( 192 | "$(DERIVED_FILE_DIR)/Pods-SwiftSortUtilsTests-checkManifestLockResult.txt", 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | shellPath = /bin/sh; 196 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 197 | showEnvVarsInLog = 0; 198 | }; 199 | 2E36FF6F006116F848263CE0 /* [CP] Embed Pods Frameworks */ = { 200 | isa = PBXShellScriptBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | ); 204 | inputPaths = ( 205 | "${PODS_ROOT}/Target Support Files/Pods-SwiftSortUtilsTests/Pods-SwiftSortUtilsTests-frameworks.sh", 206 | "${BUILT_PRODUCTS_DIR}/SwiftSortUtils/SwiftSortUtils.framework", 207 | ); 208 | name = "[CP] Embed Pods Frameworks"; 209 | outputPaths = ( 210 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftSortUtils.framework", 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | shellPath = /bin/sh; 214 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SwiftSortUtilsTests/Pods-SwiftSortUtilsTests-frameworks.sh\"\n"; 215 | showEnvVarsInLog = 0; 216 | }; 217 | /* End PBXShellScriptBuildPhase section */ 218 | 219 | /* Begin PBXSourcesBuildPhase section */ 220 | 6783047F1DCF72DB0037C44F /* Sources */ = { 221 | isa = PBXSourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | 678304861DCF72DB0037C44F /* SwiftSortUtilsTests.swift in Sources */, 225 | ); 226 | runOnlyForDeploymentPostprocessing = 0; 227 | }; 228 | /* End PBXSourcesBuildPhase section */ 229 | 230 | /* Begin XCBuildConfiguration section */ 231 | 607FACED1AFB9204008FA782 /* Debug */ = { 232 | isa = XCBuildConfiguration; 233 | buildSettings = { 234 | ALWAYS_SEARCH_USER_PATHS = NO; 235 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 236 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 237 | CLANG_CXX_LIBRARY = "libc++"; 238 | CLANG_ENABLE_MODULES = YES; 239 | CLANG_ENABLE_OBJC_ARC = YES; 240 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 241 | CLANG_WARN_BOOL_CONVERSION = YES; 242 | CLANG_WARN_COMMA = YES; 243 | CLANG_WARN_CONSTANT_CONVERSION = YES; 244 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 245 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 246 | CLANG_WARN_EMPTY_BODY = YES; 247 | CLANG_WARN_ENUM_CONVERSION = YES; 248 | CLANG_WARN_INFINITE_RECURSION = YES; 249 | CLANG_WARN_INT_CONVERSION = YES; 250 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 251 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 252 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 253 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 254 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 255 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 256 | CLANG_WARN_STRICT_PROTOTYPES = YES; 257 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 258 | CLANG_WARN_UNREACHABLE_CODE = YES; 259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 260 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 261 | COPY_PHASE_STRIP = NO; 262 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 263 | ENABLE_STRICT_OBJC_MSGSEND = YES; 264 | ENABLE_TESTABILITY = YES; 265 | GCC_C_LANGUAGE_STANDARD = gnu99; 266 | GCC_DYNAMIC_NO_PIC = NO; 267 | GCC_NO_COMMON_BLOCKS = YES; 268 | GCC_OPTIMIZATION_LEVEL = 0; 269 | GCC_PREPROCESSOR_DEFINITIONS = ( 270 | "DEBUG=1", 271 | "$(inherited)", 272 | ); 273 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 274 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 275 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 276 | GCC_WARN_UNDECLARED_SELECTOR = YES; 277 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 278 | GCC_WARN_UNUSED_FUNCTION = YES; 279 | GCC_WARN_UNUSED_VARIABLE = YES; 280 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 281 | MTL_ENABLE_DEBUG_INFO = YES; 282 | ONLY_ACTIVE_ARCH = YES; 283 | SDKROOT = iphoneos; 284 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 285 | SWIFT_VERSION = 5.0; 286 | }; 287 | name = Debug; 288 | }; 289 | 607FACEE1AFB9204008FA782 /* Release */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ALWAYS_SEARCH_USER_PATHS = NO; 293 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 294 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 295 | CLANG_CXX_LIBRARY = "libc++"; 296 | CLANG_ENABLE_MODULES = YES; 297 | CLANG_ENABLE_OBJC_ARC = YES; 298 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 299 | CLANG_WARN_BOOL_CONVERSION = YES; 300 | CLANG_WARN_COMMA = YES; 301 | CLANG_WARN_CONSTANT_CONVERSION = YES; 302 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 303 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 304 | CLANG_WARN_EMPTY_BODY = YES; 305 | CLANG_WARN_ENUM_CONVERSION = YES; 306 | CLANG_WARN_INFINITE_RECURSION = YES; 307 | CLANG_WARN_INT_CONVERSION = YES; 308 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 309 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 310 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 311 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 312 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 313 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 314 | CLANG_WARN_STRICT_PROTOTYPES = YES; 315 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 316 | CLANG_WARN_UNREACHABLE_CODE = YES; 317 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 318 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 319 | COPY_PHASE_STRIP = NO; 320 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 321 | ENABLE_NS_ASSERTIONS = NO; 322 | ENABLE_STRICT_OBJC_MSGSEND = YES; 323 | GCC_C_LANGUAGE_STANDARD = gnu99; 324 | GCC_NO_COMMON_BLOCKS = YES; 325 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 326 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 327 | GCC_WARN_UNDECLARED_SELECTOR = YES; 328 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 329 | GCC_WARN_UNUSED_FUNCTION = YES; 330 | GCC_WARN_UNUSED_VARIABLE = YES; 331 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 332 | MTL_ENABLE_DEBUG_INFO = NO; 333 | SDKROOT = iphoneos; 334 | SWIFT_VERSION = 5.0; 335 | VALIDATE_PRODUCT = YES; 336 | }; 337 | name = Release; 338 | }; 339 | 678304881DCF72DB0037C44F /* Debug */ = { 340 | isa = XCBuildConfiguration; 341 | baseConfigurationReference = D12A97782F25D8B648886146 /* Pods-SwiftSortUtilsTests.debug.xcconfig */; 342 | buildSettings = { 343 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 344 | CLANG_ANALYZER_NONNULL = YES; 345 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 346 | CLANG_WARN_INFINITE_RECURSION = YES; 347 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 348 | DEBUG_INFORMATION_FORMAT = dwarf; 349 | DEVELOPMENT_TEAM = G7C8M95922; 350 | ENABLE_TESTABILITY = YES; 351 | INFOPLIST_FILE = SwiftSortUtilsTests/Info.plist; 352 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 353 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 354 | PRODUCT_BUNDLE_IDENTIFIER = com.lockitnetwork.SwiftSortUtilsTests; 355 | PRODUCT_NAME = "$(TARGET_NAME)"; 356 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 357 | }; 358 | name = Debug; 359 | }; 360 | 678304891DCF72DB0037C44F /* Release */ = { 361 | isa = XCBuildConfiguration; 362 | baseConfigurationReference = 7F428392DC369563D2A6A244 /* Pods-SwiftSortUtilsTests.release.xcconfig */; 363 | buildSettings = { 364 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 365 | CLANG_ANALYZER_NONNULL = YES; 366 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 367 | CLANG_WARN_INFINITE_RECURSION = YES; 368 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 369 | DEVELOPMENT_TEAM = G7C8M95922; 370 | INFOPLIST_FILE = SwiftSortUtilsTests/Info.plist; 371 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 372 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 373 | PRODUCT_BUNDLE_IDENTIFIER = com.lockitnetwork.SwiftSortUtilsTests; 374 | PRODUCT_NAME = "$(TARGET_NAME)"; 375 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 376 | }; 377 | name = Release; 378 | }; 379 | /* End XCBuildConfiguration section */ 380 | 381 | /* Begin XCConfigurationList section */ 382 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "SwiftSortUtils" */ = { 383 | isa = XCConfigurationList; 384 | buildConfigurations = ( 385 | 607FACED1AFB9204008FA782 /* Debug */, 386 | 607FACEE1AFB9204008FA782 /* Release */, 387 | ); 388 | defaultConfigurationIsVisible = 0; 389 | defaultConfigurationName = Release; 390 | }; 391 | 6783048A1DCF72DB0037C44F /* Build configuration list for PBXNativeTarget "SwiftSortUtilsTests" */ = { 392 | isa = XCConfigurationList; 393 | buildConfigurations = ( 394 | 678304881DCF72DB0037C44F /* Debug */, 395 | 678304891DCF72DB0037C44F /* Release */, 396 | ); 397 | defaultConfigurationIsVisible = 0; 398 | defaultConfigurationName = Release; 399 | }; 400 | /* End XCConfigurationList section */ 401 | }; 402 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 403 | } 404 | --------------------------------------------------------------------------------