├── .gitignore ├── LinqToObjectiveC.h ├── LinqToObjectiveC.podspec ├── LinqToObjectiveC ├── LinqToObjectiveC-iOS-dynamic │ ├── Info.plist │ └── LinqToObjectiveC-iOS-dynamic.h ├── LinqToObjectiveC-iOS-static │ ├── Info.plist │ └── LinqToObjectiveC-iOS-static.h ├── LinqToObjectiveC.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── LinqToObjectiveC-iOS-dynamic.xcscheme └── LinqToObjectiveCTests │ └── Info.plist ├── LinqToObjectiveCTest ├── .gitignore ├── LinqToObjectiveCTest.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── LinqToObjectiveCTest.xccheckout ├── LinqToObjectiveCTest │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── LinqToObjectiveCTest-Info.plist │ ├── LinqToObjectiveCTest-Prefix.pch │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m └── LinqToObjectiveCTestTests │ ├── LinqToObjectiveCTestTests-Info.plist │ ├── MacroTest.h │ ├── MacroTest.m │ ├── NSArrayLinqExtensionsTest.h │ ├── NSArrayLinqExtensionsTest.m │ ├── NSDictionaryLinqExtensionsTest.h │ ├── NSDictionaryLinqExtensionsTest.m │ ├── Person.h │ ├── Person.m │ ├── ScenarioTests.h │ ├── ScenarioTests.m │ └── en.lproj │ └── InfoPlist.strings ├── MIT-LICENSE.txt ├── NSArray+LinqExtensions.h ├── NSArray+LinqExtensions.m ├── NSDictionary+LinqExtensions.h ├── NSDictionary+LinqExtensions.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # .gitignore file for Xcode4 / OS X Source projects 3 | # 4 | # Version 2.0 5 | # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects 6 | # 7 | # 2013 updates: 8 | # - fixed the broken "save personal Schemes" 9 | # 10 | # NB: if you are storing "built" products, this WILL NOT WORK, 11 | # and you should use a different .gitignore (or none at all) 12 | # This file is for SOURCE projects, where there are many extra 13 | # files that we want to exclude 14 | # 15 | ######################### 16 | 17 | ##### 18 | # OS X temporary files that should never be committed 19 | 20 | .DS_Store 21 | *.swp 22 | *.lock 23 | profile 24 | 25 | 26 | #### 27 | # Xcode temporary files that should never be committed 28 | # 29 | # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... 30 | 31 | *~.nib 32 | 33 | 34 | #### 35 | # Xcode build files - 36 | # 37 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" 38 | 39 | DerivedData/ 40 | 41 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" 42 | 43 | build/ 44 | 45 | 46 | ##### 47 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) 48 | # 49 | # This is complicated: 50 | # 51 | # SOMETIMES you need to put this file in version control. 52 | # Apple designed it poorly - if you use "custom executables", they are 53 | # saved in this file. 54 | # 99% of projects do NOT use those, so they do NOT want to version control this file. 55 | # ..but if you're in the 1%, comment out the line "*.pbxuser" 56 | 57 | *.pbxuser 58 | *.mode1v3 59 | *.mode2v3 60 | *.perspectivev3 61 | # NB: also, whitelist the default ones, some projects need to use these 62 | !default.pbxuser 63 | !default.mode1v3 64 | !default.mode2v3 65 | !default.perspectivev3 66 | 67 | 68 | #### 69 | # Xcode 4 - semi-personal settings 70 | # 71 | # 72 | # OPTION 1: --------------------------------- 73 | # throw away ALL personal settings (including custom schemes! 74 | # - unless they are "shared") 75 | # 76 | # NB: this is exclusive with OPTION 2 below 77 | xcuserdata 78 | 79 | # OPTION 2: --------------------------------- 80 | # get rid of ALL personal settings, but KEEP SOME OF THEM 81 | # - NB: you must manually uncomment the bits you want to keep 82 | # 83 | # NB: this is exclusive with OPTION 1 above 84 | # 85 | #xcuserdata/**/* 86 | 87 | # (requires option 2 above): Personal Schemes 88 | # 89 | #!xcuserdata/**/xcschemes/* 90 | 91 | #### 92 | # XCode 4 workspaces - more detailed 93 | # 94 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :) 95 | # 96 | # Workspace layout is quite spammy. For reference: 97 | # 98 | # /(root)/ 99 | # /(project-name).xcodeproj/ 100 | # project.pbxproj 101 | # /project.xcworkspace/ 102 | # contents.xcworkspacedata 103 | # /xcuserdata/ 104 | # /(your name)/xcuserdatad/ 105 | # UserInterfaceState.xcuserstate 106 | # /xcsshareddata/ 107 | # /xcschemes/ 108 | # (shared scheme name).xcscheme 109 | # /xcuserdata/ 110 | # /(your name)/xcuserdatad/ 111 | # (private scheme).xcscheme 112 | # xcschememanagement.plist 113 | # 114 | # 115 | 116 | #### 117 | # Xcode 4 - Deprecated classes 118 | # 119 | # Allegedly, if you manually "deprecate" your classes, they get moved here. 120 | # 121 | # We're using source-control, so this is a "feature" that we do not want! 122 | 123 | *.moved-aside 124 | 125 | 126 | #### 127 | # UNKNOWN: recommended by others, but I can't discover what these files are 128 | # 129 | # ...none. Everything is now explained. 130 | -------------------------------------------------------------------------------- /LinqToObjectiveC.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | #import 4 | 5 | -------------------------------------------------------------------------------- /LinqToObjectiveC.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'LinqToObjectiveC' 3 | s.version = '2.1.0' 4 | s.summary = 'Brings a Linq-style fluent query API to Objective-C.' 5 | s.author = { 6 | 'Colin Eberhardt' => 'colin.eberhardt@gmail.com' 7 | } 8 | s.source = { 9 | :git => 'https://github.com/ColinEberhardt/LinqToObjectiveC.git', 10 | :tag => '2.1.0' 11 | } 12 | s.license = { 13 | :type => 'MIT', 14 | :file => 'MIT-LICENSE.txt' 15 | } 16 | s.source_files = '*.{h,m}' 17 | s.homepage = 'https://github.com/ColinEberhardt/LinqToObjectiveC' 18 | s.requires_arc = true 19 | end 20 | -------------------------------------------------------------------------------- /LinqToObjectiveC/LinqToObjectiveC-iOS-dynamic/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.dodikk.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /LinqToObjectiveC/LinqToObjectiveC-iOS-dynamic/LinqToObjectiveC-iOS-dynamic.h: -------------------------------------------------------------------------------- 1 | // 2 | // LinqToObjectiveC-iOS-dynamic.h 3 | // LinqToObjectiveC-iOS-dynamic 4 | // 5 | // Created by dodikk on 3/14/15. 6 | // Copyright (c) 2015 scottlogic. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for LinqToObjectiveC-iOS-dynamic. 12 | FOUNDATION_EXPORT double LinqToObjectiveC_iOS_dynamicVersionNumber; 13 | 14 | //! Project version string for LinqToObjectiveC-iOS-dynamic. 15 | FOUNDATION_EXPORT const unsigned char LinqToObjectiveC_iOS_dynamicVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /LinqToObjectiveC/LinqToObjectiveC-iOS-static/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.dodikk.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /LinqToObjectiveC/LinqToObjectiveC-iOS-static/LinqToObjectiveC-iOS-static.h: -------------------------------------------------------------------------------- 1 | // 2 | // LinqToObjectiveC-iOS-static.h 3 | // LinqToObjectiveC-iOS-static 4 | // 5 | // Created by dodikk on 3/14/15. 6 | // Copyright (c) 2015 scottlogic. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for LinqToObjectiveC-iOS-static. 12 | FOUNDATION_EXPORT double LinqToObjectiveC_iOS_staticVersionNumber; 13 | 14 | //! Project version string for LinqToObjectiveC-iOS-static. 15 | FOUNDATION_EXPORT const unsigned char LinqToObjectiveC_iOS_staticVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /LinqToObjectiveC/LinqToObjectiveC.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7E8F43A11A8B931C000F5D01 /* NSArray+LinqExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E8F439E1A8B931C000F5D01 /* NSArray+LinqExtensions.m */; }; 11 | 7E8F43A21A8B931C000F5D01 /* NSDictionary+LinqExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E8F43A01A8B931C000F5D01 /* NSDictionary+LinqExtensions.m */; }; 12 | 7EEE35AD1AB4711000668C3E /* LinqToObjectiveC-iOS-dynamic.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EEE35AC1AB4711000668C3E /* LinqToObjectiveC-iOS-dynamic.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 7EEE35C11AB4712200668C3E /* NSArray+LinqExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E8F439E1A8B931C000F5D01 /* NSArray+LinqExtensions.m */; }; 14 | 7EEE35C21AB4712200668C3E /* NSDictionary+LinqExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E8F43A01A8B931C000F5D01 /* NSDictionary+LinqExtensions.m */; }; 15 | 7EEE35C31AB4712600668C3E /* NSArray+LinqExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E8F439D1A8B931C000F5D01 /* NSArray+LinqExtensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | 7EEE35C41AB4712600668C3E /* NSDictionary+LinqExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E8F439F1A8B931C000F5D01 /* NSDictionary+LinqExtensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | 7EEE35C51AB4712C00668C3E /* LinqToObjectiveC.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E8F439C1A8B931C000F5D01 /* LinqToObjectiveC.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18 | 7EEE35D01AB4718500668C3E /* LinqToObjectiveC-iOS-static.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EEE35CF1AB4718500668C3E /* LinqToObjectiveC-iOS-static.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 7EEE35E41AB471BC00668C3E /* NSArray+LinqExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E8F439E1A8B931C000F5D01 /* NSArray+LinqExtensions.m */; }; 20 | 7EEE35E51AB471BC00668C3E /* NSDictionary+LinqExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E8F43A01A8B931C000F5D01 /* NSDictionary+LinqExtensions.m */; }; 21 | 7EEE35E61AB471C200668C3E /* LinqToObjectiveC.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E8F439C1A8B931C000F5D01 /* LinqToObjectiveC.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | 7EEE35E71AB471C200668C3E /* NSArray+LinqExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E8F439D1A8B931C000F5D01 /* NSArray+LinqExtensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | 7EEE35E81AB471C200668C3E /* NSDictionary+LinqExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E8F439F1A8B931C000F5D01 /* NSDictionary+LinqExtensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXCopyFilesBuildPhase section */ 27 | 7E8F437F1A8B92D5000F5D01 /* CopyFiles */ = { 28 | isa = PBXCopyFilesBuildPhase; 29 | buildActionMask = 2147483647; 30 | dstPath = "include/$(PRODUCT_NAME)"; 31 | dstSubfolderSpec = 16; 32 | files = ( 33 | ); 34 | runOnlyForDeploymentPostprocessing = 0; 35 | }; 36 | /* End PBXCopyFilesBuildPhase section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 7E8F43811A8B92D5000F5D01 /* libLinqToObjectiveC.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libLinqToObjectiveC.a; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 7E8F43921A8B92D5000F5D01 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | 7E8F439C1A8B931C000F5D01 /* LinqToObjectiveC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LinqToObjectiveC.h; path = ../LinqToObjectiveC.h; sourceTree = ""; }; 42 | 7E8F439D1A8B931C000F5D01 /* NSArray+LinqExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+LinqExtensions.h"; path = "../NSArray+LinqExtensions.h"; sourceTree = ""; }; 43 | 7E8F439E1A8B931C000F5D01 /* NSArray+LinqExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+LinqExtensions.m"; path = "../NSArray+LinqExtensions.m"; sourceTree = ""; }; 44 | 7E8F439F1A8B931C000F5D01 /* NSDictionary+LinqExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+LinqExtensions.h"; path = "../NSDictionary+LinqExtensions.h"; sourceTree = ""; }; 45 | 7E8F43A01A8B931C000F5D01 /* NSDictionary+LinqExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+LinqExtensions.m"; path = "../NSDictionary+LinqExtensions.m"; sourceTree = ""; }; 46 | 7EEE35A81AB4711000668C3E /* LinqToObjectiveC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LinqToObjectiveC.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 7EEE35AB1AB4711000668C3E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 7EEE35AC1AB4711000668C3E /* LinqToObjectiveC-iOS-dynamic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LinqToObjectiveC-iOS-dynamic.h"; sourceTree = ""; }; 49 | 7EEE35CB1AB4718500668C3E /* LinqToObjectiveC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LinqToObjectiveC.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 7EEE35CE1AB4718500668C3E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 7EEE35CF1AB4718500668C3E /* LinqToObjectiveC-iOS-static.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LinqToObjectiveC-iOS-static.h"; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 7E8F437E1A8B92D5000F5D01 /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | 7EEE35A41AB4711000668C3E /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | 7EEE35C71AB4718500668C3E /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | /* End PBXFrameworksBuildPhase section */ 77 | 78 | /* Begin PBXGroup section */ 79 | 7E8F43781A8B92D5000F5D01 = { 80 | isa = PBXGroup; 81 | children = ( 82 | 7E8F439B1A8B9310000F5D01 /* Sources */, 83 | 7E8F43901A8B92D5000F5D01 /* LinqToObjectiveCTests */, 84 | 7EEE35A91AB4711000668C3E /* LinqToObjectiveC-iOS-dynamic */, 85 | 7EEE35CC1AB4718500668C3E /* LinqToObjectiveC-iOS-static */, 86 | 7E8F43821A8B92D5000F5D01 /* Products */, 87 | ); 88 | sourceTree = ""; 89 | }; 90 | 7E8F43821A8B92D5000F5D01 /* Products */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 7E8F43811A8B92D5000F5D01 /* libLinqToObjectiveC.a */, 94 | 7EEE35A81AB4711000668C3E /* LinqToObjectiveC.framework */, 95 | 7EEE35CB1AB4718500668C3E /* LinqToObjectiveC.framework */, 96 | ); 97 | name = Products; 98 | sourceTree = ""; 99 | }; 100 | 7E8F43901A8B92D5000F5D01 /* LinqToObjectiveCTests */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 7E8F43911A8B92D5000F5D01 /* Supporting Files */, 104 | ); 105 | path = LinqToObjectiveCTests; 106 | sourceTree = ""; 107 | }; 108 | 7E8F43911A8B92D5000F5D01 /* Supporting Files */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 7E8F43921A8B92D5000F5D01 /* Info.plist */, 112 | ); 113 | name = "Supporting Files"; 114 | sourceTree = ""; 115 | }; 116 | 7E8F439B1A8B9310000F5D01 /* Sources */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 7E8F439C1A8B931C000F5D01 /* LinqToObjectiveC.h */, 120 | 7E8F439D1A8B931C000F5D01 /* NSArray+LinqExtensions.h */, 121 | 7E8F439E1A8B931C000F5D01 /* NSArray+LinqExtensions.m */, 122 | 7E8F439F1A8B931C000F5D01 /* NSDictionary+LinqExtensions.h */, 123 | 7E8F43A01A8B931C000F5D01 /* NSDictionary+LinqExtensions.m */, 124 | ); 125 | name = Sources; 126 | sourceTree = ""; 127 | }; 128 | 7EEE35A91AB4711000668C3E /* LinqToObjectiveC-iOS-dynamic */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 7EEE35AC1AB4711000668C3E /* LinqToObjectiveC-iOS-dynamic.h */, 132 | 7EEE35AA1AB4711000668C3E /* Supporting Files */, 133 | ); 134 | path = "LinqToObjectiveC-iOS-dynamic"; 135 | sourceTree = ""; 136 | }; 137 | 7EEE35AA1AB4711000668C3E /* Supporting Files */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 7EEE35AB1AB4711000668C3E /* Info.plist */, 141 | ); 142 | name = "Supporting Files"; 143 | sourceTree = ""; 144 | }; 145 | 7EEE35CC1AB4718500668C3E /* LinqToObjectiveC-iOS-static */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 7EEE35CF1AB4718500668C3E /* LinqToObjectiveC-iOS-static.h */, 149 | 7EEE35CD1AB4718500668C3E /* Supporting Files */, 150 | ); 151 | path = "LinqToObjectiveC-iOS-static"; 152 | sourceTree = ""; 153 | }; 154 | 7EEE35CD1AB4718500668C3E /* Supporting Files */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 7EEE35CE1AB4718500668C3E /* Info.plist */, 158 | ); 159 | name = "Supporting Files"; 160 | sourceTree = ""; 161 | }; 162 | /* End PBXGroup section */ 163 | 164 | /* Begin PBXHeadersBuildPhase section */ 165 | 7EEE35A51AB4711000668C3E /* Headers */ = { 166 | isa = PBXHeadersBuildPhase; 167 | buildActionMask = 2147483647; 168 | files = ( 169 | 7EEE35C41AB4712600668C3E /* NSDictionary+LinqExtensions.h in Headers */, 170 | 7EEE35C51AB4712C00668C3E /* LinqToObjectiveC.h in Headers */, 171 | 7EEE35AD1AB4711000668C3E /* LinqToObjectiveC-iOS-dynamic.h in Headers */, 172 | 7EEE35C31AB4712600668C3E /* NSArray+LinqExtensions.h in Headers */, 173 | ); 174 | runOnlyForDeploymentPostprocessing = 0; 175 | }; 176 | 7EEE35C81AB4718500668C3E /* Headers */ = { 177 | isa = PBXHeadersBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | 7EEE35D01AB4718500668C3E /* LinqToObjectiveC-iOS-static.h in Headers */, 181 | 7EEE35E81AB471C200668C3E /* NSDictionary+LinqExtensions.h in Headers */, 182 | 7EEE35E71AB471C200668C3E /* NSArray+LinqExtensions.h in Headers */, 183 | 7EEE35E61AB471C200668C3E /* LinqToObjectiveC.h in Headers */, 184 | ); 185 | runOnlyForDeploymentPostprocessing = 0; 186 | }; 187 | /* End PBXHeadersBuildPhase section */ 188 | 189 | /* Begin PBXNativeTarget section */ 190 | 7E8F43801A8B92D5000F5D01 /* LinqToObjectiveC */ = { 191 | isa = PBXNativeTarget; 192 | buildConfigurationList = 7E8F43951A8B92D5000F5D01 /* Build configuration list for PBXNativeTarget "LinqToObjectiveC" */; 193 | buildPhases = ( 194 | 7E8F437D1A8B92D5000F5D01 /* Sources */, 195 | 7E8F437E1A8B92D5000F5D01 /* Frameworks */, 196 | 7E8F437F1A8B92D5000F5D01 /* CopyFiles */, 197 | ); 198 | buildRules = ( 199 | ); 200 | dependencies = ( 201 | ); 202 | name = LinqToObjectiveC; 203 | productName = LinqToObjectiveC; 204 | productReference = 7E8F43811A8B92D5000F5D01 /* libLinqToObjectiveC.a */; 205 | productType = "com.apple.product-type.library.static"; 206 | }; 207 | 7EEE35A71AB4711000668C3E /* LinqToObjectiveC-iOS-dynamic */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 7EEE35BF1AB4711000668C3E /* Build configuration list for PBXNativeTarget "LinqToObjectiveC-iOS-dynamic" */; 210 | buildPhases = ( 211 | 7EEE35A31AB4711000668C3E /* Sources */, 212 | 7EEE35A41AB4711000668C3E /* Frameworks */, 213 | 7EEE35A51AB4711000668C3E /* Headers */, 214 | 7EEE35A61AB4711000668C3E /* Resources */, 215 | ); 216 | buildRules = ( 217 | ); 218 | dependencies = ( 219 | ); 220 | name = "LinqToObjectiveC-iOS-dynamic"; 221 | productName = "LinqToObjectiveC-iOS-dynamic"; 222 | productReference = 7EEE35A81AB4711000668C3E /* LinqToObjectiveC.framework */; 223 | productType = "com.apple.product-type.framework"; 224 | }; 225 | 7EEE35CA1AB4718500668C3E /* LinqToObjectiveC-iOS-static */ = { 226 | isa = PBXNativeTarget; 227 | buildConfigurationList = 7EEE35DE1AB4718500668C3E /* Build configuration list for PBXNativeTarget "LinqToObjectiveC-iOS-static" */; 228 | buildPhases = ( 229 | 7EEE35C61AB4718500668C3E /* Sources */, 230 | 7EEE35C71AB4718500668C3E /* Frameworks */, 231 | 7EEE35C81AB4718500668C3E /* Headers */, 232 | 7EEE35C91AB4718500668C3E /* Resources */, 233 | ); 234 | buildRules = ( 235 | ); 236 | dependencies = ( 237 | ); 238 | name = "LinqToObjectiveC-iOS-static"; 239 | productName = "LinqToObjectiveC-iOS-static"; 240 | productReference = 7EEE35CB1AB4718500668C3E /* LinqToObjectiveC.framework */; 241 | productType = "com.apple.product-type.framework"; 242 | }; 243 | /* End PBXNativeTarget section */ 244 | 245 | /* Begin PBXProject section */ 246 | 7E8F43791A8B92D5000F5D01 /* Project object */ = { 247 | isa = PBXProject; 248 | attributes = { 249 | LastUpgradeCheck = 0610; 250 | ORGANIZATIONNAME = scottlogic; 251 | TargetAttributes = { 252 | 7E8F43801A8B92D5000F5D01 = { 253 | CreatedOnToolsVersion = 6.1.1; 254 | }; 255 | 7EEE35A71AB4711000668C3E = { 256 | CreatedOnToolsVersion = 6.1.1; 257 | }; 258 | 7EEE35CA1AB4718500668C3E = { 259 | CreatedOnToolsVersion = 6.1.1; 260 | }; 261 | }; 262 | }; 263 | buildConfigurationList = 7E8F437C1A8B92D5000F5D01 /* Build configuration list for PBXProject "LinqToObjectiveC" */; 264 | compatibilityVersion = "Xcode 3.2"; 265 | developmentRegion = English; 266 | hasScannedForEncodings = 0; 267 | knownRegions = ( 268 | en, 269 | ); 270 | mainGroup = 7E8F43781A8B92D5000F5D01; 271 | productRefGroup = 7E8F43821A8B92D5000F5D01 /* Products */; 272 | projectDirPath = ""; 273 | projectRoot = ""; 274 | targets = ( 275 | 7E8F43801A8B92D5000F5D01 /* LinqToObjectiveC */, 276 | 7EEE35A71AB4711000668C3E /* LinqToObjectiveC-iOS-dynamic */, 277 | 7EEE35CA1AB4718500668C3E /* LinqToObjectiveC-iOS-static */, 278 | ); 279 | }; 280 | /* End PBXProject section */ 281 | 282 | /* Begin PBXResourcesBuildPhase section */ 283 | 7EEE35A61AB4711000668C3E /* Resources */ = { 284 | isa = PBXResourcesBuildPhase; 285 | buildActionMask = 2147483647; 286 | files = ( 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | 7EEE35C91AB4718500668C3E /* Resources */ = { 291 | isa = PBXResourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | }; 297 | /* End PBXResourcesBuildPhase section */ 298 | 299 | /* Begin PBXSourcesBuildPhase section */ 300 | 7E8F437D1A8B92D5000F5D01 /* Sources */ = { 301 | isa = PBXSourcesBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | 7E8F43A21A8B931C000F5D01 /* NSDictionary+LinqExtensions.m in Sources */, 305 | 7E8F43A11A8B931C000F5D01 /* NSArray+LinqExtensions.m in Sources */, 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | 7EEE35A31AB4711000668C3E /* Sources */ = { 310 | isa = PBXSourcesBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | 7EEE35C21AB4712200668C3E /* NSDictionary+LinqExtensions.m in Sources */, 314 | 7EEE35C11AB4712200668C3E /* NSArray+LinqExtensions.m in Sources */, 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | }; 318 | 7EEE35C61AB4718500668C3E /* Sources */ = { 319 | isa = PBXSourcesBuildPhase; 320 | buildActionMask = 2147483647; 321 | files = ( 322 | 7EEE35E51AB471BC00668C3E /* NSDictionary+LinqExtensions.m in Sources */, 323 | 7EEE35E41AB471BC00668C3E /* NSArray+LinqExtensions.m in Sources */, 324 | ); 325 | runOnlyForDeploymentPostprocessing = 0; 326 | }; 327 | /* End PBXSourcesBuildPhase section */ 328 | 329 | /* Begin XCBuildConfiguration section */ 330 | 7E8F43931A8B92D5000F5D01 /* Debug */ = { 331 | isa = XCBuildConfiguration; 332 | buildSettings = { 333 | ALWAYS_SEARCH_USER_PATHS = NO; 334 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 335 | CLANG_CXX_LIBRARY = "libc++"; 336 | CLANG_ENABLE_MODULES = YES; 337 | CLANG_ENABLE_OBJC_ARC = YES; 338 | CLANG_WARN_BOOL_CONVERSION = YES; 339 | CLANG_WARN_CONSTANT_CONVERSION = YES; 340 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 341 | CLANG_WARN_EMPTY_BODY = YES; 342 | CLANG_WARN_ENUM_CONVERSION = YES; 343 | CLANG_WARN_INT_CONVERSION = YES; 344 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 345 | CLANG_WARN_UNREACHABLE_CODE = YES; 346 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 347 | COPY_PHASE_STRIP = NO; 348 | ENABLE_STRICT_OBJC_MSGSEND = YES; 349 | GCC_C_LANGUAGE_STANDARD = gnu99; 350 | GCC_DYNAMIC_NO_PIC = NO; 351 | GCC_OPTIMIZATION_LEVEL = 0; 352 | GCC_PREPROCESSOR_DEFINITIONS = ( 353 | "DEBUG=1", 354 | "$(inherited)", 355 | ); 356 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 357 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 358 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 359 | GCC_WARN_UNDECLARED_SELECTOR = YES; 360 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 361 | GCC_WARN_UNUSED_FUNCTION = YES; 362 | GCC_WARN_UNUSED_VARIABLE = YES; 363 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 364 | MTL_ENABLE_DEBUG_INFO = YES; 365 | ONLY_ACTIVE_ARCH = YES; 366 | SDKROOT = iphoneos; 367 | }; 368 | name = Debug; 369 | }; 370 | 7E8F43941A8B92D5000F5D01 /* Release */ = { 371 | isa = XCBuildConfiguration; 372 | buildSettings = { 373 | ALWAYS_SEARCH_USER_PATHS = NO; 374 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 375 | CLANG_CXX_LIBRARY = "libc++"; 376 | CLANG_ENABLE_MODULES = YES; 377 | CLANG_ENABLE_OBJC_ARC = YES; 378 | CLANG_WARN_BOOL_CONVERSION = YES; 379 | CLANG_WARN_CONSTANT_CONVERSION = YES; 380 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 381 | CLANG_WARN_EMPTY_BODY = YES; 382 | CLANG_WARN_ENUM_CONVERSION = YES; 383 | CLANG_WARN_INT_CONVERSION = YES; 384 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 385 | CLANG_WARN_UNREACHABLE_CODE = YES; 386 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 387 | COPY_PHASE_STRIP = YES; 388 | ENABLE_NS_ASSERTIONS = NO; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | GCC_C_LANGUAGE_STANDARD = gnu99; 391 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 392 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 393 | GCC_WARN_UNDECLARED_SELECTOR = YES; 394 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 395 | GCC_WARN_UNUSED_FUNCTION = YES; 396 | GCC_WARN_UNUSED_VARIABLE = YES; 397 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 398 | MTL_ENABLE_DEBUG_INFO = NO; 399 | SDKROOT = iphoneos; 400 | VALIDATE_PRODUCT = YES; 401 | }; 402 | name = Release; 403 | }; 404 | 7E8F43961A8B92D5000F5D01 /* Debug */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | OTHER_LDFLAGS = "-ObjC"; 408 | PRODUCT_NAME = "$(TARGET_NAME)"; 409 | SKIP_INSTALL = YES; 410 | }; 411 | name = Debug; 412 | }; 413 | 7E8F43971A8B92D5000F5D01 /* Release */ = { 414 | isa = XCBuildConfiguration; 415 | buildSettings = { 416 | OTHER_LDFLAGS = "-ObjC"; 417 | PRODUCT_NAME = "$(TARGET_NAME)"; 418 | SKIP_INSTALL = YES; 419 | }; 420 | name = Release; 421 | }; 422 | 7EEE35BB1AB4711000668C3E /* Debug */ = { 423 | isa = XCBuildConfiguration; 424 | buildSettings = { 425 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 426 | CURRENT_PROJECT_VERSION = 1; 427 | DEFINES_MODULE = YES; 428 | DYLIB_COMPATIBILITY_VERSION = 1; 429 | DYLIB_CURRENT_VERSION = 1; 430 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 431 | GCC_PREPROCESSOR_DEFINITIONS = ( 432 | "DEBUG=1", 433 | "$(inherited)", 434 | ); 435 | INFOPLIST_FILE = "LinqToObjectiveC-iOS-dynamic/Info.plist"; 436 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 437 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 438 | PRODUCT_NAME = LinqToObjectiveC; 439 | SKIP_INSTALL = YES; 440 | TARGETED_DEVICE_FAMILY = "1,2"; 441 | VERSIONING_SYSTEM = "apple-generic"; 442 | VERSION_INFO_PREFIX = ""; 443 | }; 444 | name = Debug; 445 | }; 446 | 7EEE35BC1AB4711000668C3E /* Release */ = { 447 | isa = XCBuildConfiguration; 448 | buildSettings = { 449 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 450 | CURRENT_PROJECT_VERSION = 1; 451 | DEFINES_MODULE = YES; 452 | DYLIB_COMPATIBILITY_VERSION = 1; 453 | DYLIB_CURRENT_VERSION = 1; 454 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 455 | INFOPLIST_FILE = "LinqToObjectiveC-iOS-dynamic/Info.plist"; 456 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 457 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 458 | PRODUCT_NAME = LinqToObjectiveC; 459 | SKIP_INSTALL = YES; 460 | TARGETED_DEVICE_FAMILY = "1,2"; 461 | VERSIONING_SYSTEM = "apple-generic"; 462 | VERSION_INFO_PREFIX = ""; 463 | }; 464 | name = Release; 465 | }; 466 | 7EEE35DF1AB4718500668C3E /* Debug */ = { 467 | isa = XCBuildConfiguration; 468 | buildSettings = { 469 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 470 | CURRENT_PROJECT_VERSION = 1; 471 | DEFINES_MODULE = YES; 472 | DYLIB_COMPATIBILITY_VERSION = 1; 473 | DYLIB_CURRENT_VERSION = 1; 474 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 475 | GCC_PREPROCESSOR_DEFINITIONS = ( 476 | "DEBUG=1", 477 | "$(inherited)", 478 | ); 479 | INFOPLIST_FILE = "LinqToObjectiveC-iOS-static/Info.plist"; 480 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 481 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 482 | MACH_O_TYPE = staticlib; 483 | PRODUCT_NAME = LinqToObjectiveC; 484 | SKIP_INSTALL = YES; 485 | TARGETED_DEVICE_FAMILY = "1,2"; 486 | VERSIONING_SYSTEM = "apple-generic"; 487 | VERSION_INFO_PREFIX = ""; 488 | }; 489 | name = Debug; 490 | }; 491 | 7EEE35E01AB4718500668C3E /* Release */ = { 492 | isa = XCBuildConfiguration; 493 | buildSettings = { 494 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 495 | CURRENT_PROJECT_VERSION = 1; 496 | DEFINES_MODULE = YES; 497 | DYLIB_COMPATIBILITY_VERSION = 1; 498 | DYLIB_CURRENT_VERSION = 1; 499 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 500 | INFOPLIST_FILE = "LinqToObjectiveC-iOS-static/Info.plist"; 501 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 502 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 503 | MACH_O_TYPE = staticlib; 504 | PRODUCT_NAME = LinqToObjectiveC; 505 | SKIP_INSTALL = YES; 506 | TARGETED_DEVICE_FAMILY = "1,2"; 507 | VERSIONING_SYSTEM = "apple-generic"; 508 | VERSION_INFO_PREFIX = ""; 509 | }; 510 | name = Release; 511 | }; 512 | /* End XCBuildConfiguration section */ 513 | 514 | /* Begin XCConfigurationList section */ 515 | 7E8F437C1A8B92D5000F5D01 /* Build configuration list for PBXProject "LinqToObjectiveC" */ = { 516 | isa = XCConfigurationList; 517 | buildConfigurations = ( 518 | 7E8F43931A8B92D5000F5D01 /* Debug */, 519 | 7E8F43941A8B92D5000F5D01 /* Release */, 520 | ); 521 | defaultConfigurationIsVisible = 0; 522 | defaultConfigurationName = Release; 523 | }; 524 | 7E8F43951A8B92D5000F5D01 /* Build configuration list for PBXNativeTarget "LinqToObjectiveC" */ = { 525 | isa = XCConfigurationList; 526 | buildConfigurations = ( 527 | 7E8F43961A8B92D5000F5D01 /* Debug */, 528 | 7E8F43971A8B92D5000F5D01 /* Release */, 529 | ); 530 | defaultConfigurationIsVisible = 0; 531 | defaultConfigurationName = Release; 532 | }; 533 | 7EEE35BF1AB4711000668C3E /* Build configuration list for PBXNativeTarget "LinqToObjectiveC-iOS-dynamic" */ = { 534 | isa = XCConfigurationList; 535 | buildConfigurations = ( 536 | 7EEE35BB1AB4711000668C3E /* Debug */, 537 | 7EEE35BC1AB4711000668C3E /* Release */, 538 | ); 539 | defaultConfigurationIsVisible = 0; 540 | }; 541 | 7EEE35DE1AB4718500668C3E /* Build configuration list for PBXNativeTarget "LinqToObjectiveC-iOS-static" */ = { 542 | isa = XCConfigurationList; 543 | buildConfigurations = ( 544 | 7EEE35DF1AB4718500668C3E /* Debug */, 545 | 7EEE35E01AB4718500668C3E /* Release */, 546 | ); 547 | defaultConfigurationIsVisible = 0; 548 | }; 549 | /* End XCConfigurationList section */ 550 | }; 551 | rootObject = 7E8F43791A8B92D5000F5D01 /* Project object */; 552 | } 553 | -------------------------------------------------------------------------------- /LinqToObjectiveC/LinqToObjectiveC.xcodeproj/xcshareddata/xcschemes/LinqToObjectiveC-iOS-dynamic.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /LinqToObjectiveC/LinqToObjectiveCTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.scottlogic.$(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 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # .gitignore file for Xcode4 / OS X Source projects 3 | # 4 | # Version 2.0 5 | # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects 6 | # 7 | # 2013 updates: 8 | # - fixed the broken "save personal Schemes" 9 | # 10 | # NB: if you are storing "built" products, this WILL NOT WORK, 11 | # and you should use a different .gitignore (or none at all) 12 | # This file is for SOURCE projects, where there are many extra 13 | # files that we want to exclude 14 | # 15 | ######################### 16 | 17 | ##### 18 | # OS X temporary files that should never be committed 19 | 20 | .DS_Store 21 | *.swp 22 | *.lock 23 | profile 24 | 25 | 26 | #### 27 | # Xcode temporary files that should never be committed 28 | # 29 | # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... 30 | 31 | *~.nib 32 | 33 | 34 | #### 35 | # Xcode build files - 36 | # 37 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" 38 | 39 | DerivedData/ 40 | 41 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" 42 | 43 | build/ 44 | 45 | 46 | ##### 47 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) 48 | # 49 | # This is complicated: 50 | # 51 | # SOMETIMES you need to put this file in version control. 52 | # Apple designed it poorly - if you use "custom executables", they are 53 | # saved in this file. 54 | # 99% of projects do NOT use those, so they do NOT want to version control this file. 55 | # ..but if you're in the 1%, comment out the line "*.pbxuser" 56 | 57 | *.pbxuser 58 | *.mode1v3 59 | *.mode2v3 60 | *.perspectivev3 61 | # NB: also, whitelist the default ones, some projects need to use these 62 | !default.pbxuser 63 | !default.mode1v3 64 | !default.mode2v3 65 | !default.perspectivev3 66 | 67 | 68 | #### 69 | # Xcode 4 - semi-personal settings 70 | # 71 | # 72 | # OPTION 1: --------------------------------- 73 | # throw away ALL personal settings (including custom schemes! 74 | # - unless they are "shared") 75 | # 76 | # NB: this is exclusive with OPTION 2 below 77 | xcuserdata 78 | 79 | # OPTION 2: --------------------------------- 80 | # get rid of ALL personal settings, but KEEP SOME OF THEM 81 | # - NB: you must manually uncomment the bits you want to keep 82 | # 83 | # NB: this is exclusive with OPTION 1 above 84 | # 85 | #xcuserdata/**/* 86 | 87 | # (requires option 2 above): Personal Schemes 88 | # 89 | #!xcuserdata/**/xcschemes/* 90 | 91 | #### 92 | # XCode 4 workspaces - more detailed 93 | # 94 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :) 95 | # 96 | # Workspace layout is quite spammy. For reference: 97 | # 98 | # /(root)/ 99 | # /(project-name).xcodeproj/ 100 | # project.pbxproj 101 | # /project.xcworkspace/ 102 | # contents.xcworkspacedata 103 | # /xcuserdata/ 104 | # /(your name)/xcuserdatad/ 105 | # UserInterfaceState.xcuserstate 106 | # /xcsshareddata/ 107 | # /xcschemes/ 108 | # (shared scheme name).xcscheme 109 | # /xcuserdata/ 110 | # /(your name)/xcuserdatad/ 111 | # (private scheme).xcscheme 112 | # xcschememanagement.plist 113 | # 114 | # 115 | 116 | #### 117 | # Xcode 4 - Deprecated classes 118 | # 119 | # Allegedly, if you manually "deprecate" your classes, they get moved here. 120 | # 121 | # We're using source-control, so this is a "feature" that we do not want! 122 | 123 | *.moved-aside 124 | 125 | #### 126 | # Cocoapods: cocoapods.org 127 | # 128 | # Ignoring these files means that whoever uses the code will first have to run: 129 | # pod install 130 | # in the App.xcodeproj directory. 131 | # This ensures the latest dependencies are used. 132 | Pods/ 133 | Podfile.lock 134 | 135 | 136 | #### 137 | # UNKNOWN: recommended by others, but I can't discover what these files are 138 | # 139 | # ...none. Everything is now explained. -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTest.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 72B9B6761848EA6C0039064C /* MacroTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 72B9B6751848EA6C0039064C /* MacroTest.m */; }; 11 | 72EC7E0E17DC4DA0009AA360 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72EC7E0D17DC4DA0009AA360 /* UIKit.framework */; }; 12 | 72EC7E1017DC4DA0009AA360 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72EC7E0F17DC4DA0009AA360 /* Foundation.framework */; }; 13 | 72EC7E1217DC4DA0009AA360 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72EC7E1117DC4DA0009AA360 /* CoreGraphics.framework */; }; 14 | 72EC7E1817DC4DA0009AA360 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 72EC7E1617DC4DA0009AA360 /* InfoPlist.strings */; }; 15 | 72EC7E1A17DC4DA0009AA360 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 72EC7E1917DC4DA0009AA360 /* main.m */; }; 16 | 72EC7E1E17DC4DA0009AA360 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 72EC7E1D17DC4DA0009AA360 /* AppDelegate.m */; }; 17 | 72EC7E2C17DC4DA0009AA360 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72EC7E2B17DC4DA0009AA360 /* SenTestingKit.framework */; }; 18 | 72EC7E2D17DC4DA0009AA360 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72EC7E0D17DC4DA0009AA360 /* UIKit.framework */; }; 19 | 72EC7E2E17DC4DA0009AA360 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72EC7E0F17DC4DA0009AA360 /* Foundation.framework */; }; 20 | 72EC7E3617DC4DA0009AA360 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 72EC7E3417DC4DA0009AA360 /* InfoPlist.strings */; }; 21 | 72EC7E4617DC4DCB009AA360 /* NSArray+LinqExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 72EC7E4417DC4DCB009AA360 /* NSArray+LinqExtensions.m */; }; 22 | 72EC7E4717DC4DCB009AA360 /* NSDictionary+LinqExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 72EC7E4517DC4DCB009AA360 /* NSDictionary+LinqExtensions.m */; }; 23 | 72EC7E6B17DC505D009AA360 /* NSArrayLinqExtensionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 72EC7E6717DC505D009AA360 /* NSArrayLinqExtensionsTest.m */; }; 24 | 72EC7E6C17DC505D009AA360 /* NSDictionaryLinqExtensionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 72EC7E6817DC505D009AA360 /* NSDictionaryLinqExtensionsTest.m */; }; 25 | 72EC7E6D17DC505D009AA360 /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = 72EC7E6917DC505D009AA360 /* Person.m */; }; 26 | 72EC7E6E17DC505D009AA360 /* ScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 72EC7E6A17DC505D009AA360 /* ScenarioTests.m */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | 72EC7E2F17DC4DA0009AA360 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 72EC7E0017DC4DA0009AA360 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 72EC7E0817DC4DA0009AA360; 35 | remoteInfo = LinqToObjectiveCTest; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 72B9B6741848EA6C0039064C /* MacroTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroTest.h; sourceTree = ""; }; 41 | 72B9B6751848EA6C0039064C /* MacroTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MacroTest.m; sourceTree = ""; }; 42 | 72EC7E0917DC4DA0009AA360 /* LinqToObjectiveCTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LinqToObjectiveCTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 72EC7E0D17DC4DA0009AA360 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 44 | 72EC7E0F17DC4DA0009AA360 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 45 | 72EC7E1117DC4DA0009AA360 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 46 | 72EC7E1517DC4DA0009AA360 /* LinqToObjectiveCTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LinqToObjectiveCTest-Info.plist"; sourceTree = ""; }; 47 | 72EC7E1717DC4DA0009AA360 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 48 | 72EC7E1917DC4DA0009AA360 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 49 | 72EC7E1B17DC4DA0009AA360 /* LinqToObjectiveCTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LinqToObjectiveCTest-Prefix.pch"; sourceTree = ""; }; 50 | 72EC7E1C17DC4DA0009AA360 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 51 | 72EC7E1D17DC4DA0009AA360 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 52 | 72EC7E2A17DC4DA0009AA360 /* LinqToObjectiveCTestTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LinqToObjectiveCTestTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 72EC7E2B17DC4DA0009AA360 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; 54 | 72EC7E3317DC4DA0009AA360 /* LinqToObjectiveCTestTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LinqToObjectiveCTestTests-Info.plist"; sourceTree = ""; }; 55 | 72EC7E3517DC4DA0009AA360 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 56 | 72EC7E4217DC4DCB009AA360 /* NSArray+LinqExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+LinqExtensions.h"; path = "../../NSArray+LinqExtensions.h"; sourceTree = ""; }; 57 | 72EC7E4317DC4DCB009AA360 /* NSDictionary+LinqExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+LinqExtensions.h"; path = "../../NSDictionary+LinqExtensions.h"; sourceTree = ""; }; 58 | 72EC7E4417DC4DCB009AA360 /* NSArray+LinqExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+LinqExtensions.m"; path = "../../NSArray+LinqExtensions.m"; sourceTree = ""; }; 59 | 72EC7E4517DC4DCB009AA360 /* NSDictionary+LinqExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+LinqExtensions.m"; path = "../../NSDictionary+LinqExtensions.m"; sourceTree = ""; }; 60 | 72EC7E6317DC505D009AA360 /* NSArrayLinqExtensionsTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSArrayLinqExtensionsTest.h; sourceTree = ""; }; 61 | 72EC7E6417DC505D009AA360 /* NSDictionaryLinqExtensionsTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSDictionaryLinqExtensionsTest.h; sourceTree = ""; }; 62 | 72EC7E6517DC505D009AA360 /* Person.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Person.h; sourceTree = ""; }; 63 | 72EC7E6617DC505D009AA360 /* ScenarioTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScenarioTests.h; sourceTree = ""; }; 64 | 72EC7E6717DC505D009AA360 /* NSArrayLinqExtensionsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSArrayLinqExtensionsTest.m; sourceTree = ""; }; 65 | 72EC7E6817DC505D009AA360 /* NSDictionaryLinqExtensionsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSDictionaryLinqExtensionsTest.m; sourceTree = ""; }; 66 | 72EC7E6917DC505D009AA360 /* Person.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Person.m; sourceTree = ""; }; 67 | 72EC7E6A17DC505D009AA360 /* ScenarioTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScenarioTests.m; sourceTree = ""; }; 68 | /* End PBXFileReference section */ 69 | 70 | /* Begin PBXFrameworksBuildPhase section */ 71 | 72EC7E0617DC4DA0009AA360 /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | 72EC7E0E17DC4DA0009AA360 /* UIKit.framework in Frameworks */, 76 | 72EC7E1017DC4DA0009AA360 /* Foundation.framework in Frameworks */, 77 | 72EC7E1217DC4DA0009AA360 /* CoreGraphics.framework in Frameworks */, 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | 72EC7E2617DC4DA0009AA360 /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | 72EC7E2C17DC4DA0009AA360 /* SenTestingKit.framework in Frameworks */, 86 | 72EC7E2D17DC4DA0009AA360 /* UIKit.framework in Frameworks */, 87 | 72EC7E2E17DC4DA0009AA360 /* Foundation.framework in Frameworks */, 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | /* End PBXFrameworksBuildPhase section */ 92 | 93 | /* Begin PBXGroup section */ 94 | 72EC7DFE17DC4DA0009AA360 = { 95 | isa = PBXGroup; 96 | children = ( 97 | 72EC7E1317DC4DA0009AA360 /* LinqToObjectiveCTest */, 98 | 72EC7E3117DC4DA0009AA360 /* LinqToObjectiveCTestTests */, 99 | 72EC7E0C17DC4DA0009AA360 /* Frameworks */, 100 | 72EC7E0A17DC4DA0009AA360 /* Products */, 101 | ); 102 | sourceTree = ""; 103 | }; 104 | 72EC7E0A17DC4DA0009AA360 /* Products */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 72EC7E0917DC4DA0009AA360 /* LinqToObjectiveCTest.app */, 108 | 72EC7E2A17DC4DA0009AA360 /* LinqToObjectiveCTestTests.octest */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 72EC7E0C17DC4DA0009AA360 /* Frameworks */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 72EC7E0D17DC4DA0009AA360 /* UIKit.framework */, 117 | 72EC7E0F17DC4DA0009AA360 /* Foundation.framework */, 118 | 72EC7E1117DC4DA0009AA360 /* CoreGraphics.framework */, 119 | 72EC7E2B17DC4DA0009AA360 /* SenTestingKit.framework */, 120 | ); 121 | name = Frameworks; 122 | sourceTree = ""; 123 | }; 124 | 72EC7E1317DC4DA0009AA360 /* LinqToObjectiveCTest */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 72EC7E1C17DC4DA0009AA360 /* AppDelegate.h */, 128 | 72EC7E1D17DC4DA0009AA360 /* AppDelegate.m */, 129 | 72EC7E1417DC4DA0009AA360 /* Supporting Files */, 130 | ); 131 | path = LinqToObjectiveCTest; 132 | sourceTree = ""; 133 | }; 134 | 72EC7E1417DC4DA0009AA360 /* Supporting Files */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 72EC7E1517DC4DA0009AA360 /* LinqToObjectiveCTest-Info.plist */, 138 | 72EC7E1617DC4DA0009AA360 /* InfoPlist.strings */, 139 | 72EC7E1917DC4DA0009AA360 /* main.m */, 140 | 72EC7E1B17DC4DA0009AA360 /* LinqToObjectiveCTest-Prefix.pch */, 141 | ); 142 | name = "Supporting Files"; 143 | sourceTree = ""; 144 | }; 145 | 72EC7E3117DC4DA0009AA360 /* LinqToObjectiveCTestTests */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 72B9B6741848EA6C0039064C /* MacroTest.h */, 149 | 72B9B6751848EA6C0039064C /* MacroTest.m */, 150 | 72EC7E6317DC505D009AA360 /* NSArrayLinqExtensionsTest.h */, 151 | 72EC7E6717DC505D009AA360 /* NSArrayLinqExtensionsTest.m */, 152 | 72EC7E6417DC505D009AA360 /* NSDictionaryLinqExtensionsTest.h */, 153 | 72EC7E6817DC505D009AA360 /* NSDictionaryLinqExtensionsTest.m */, 154 | 72EC7E6517DC505D009AA360 /* Person.h */, 155 | 72EC7E6917DC505D009AA360 /* Person.m */, 156 | 72EC7E6617DC505D009AA360 /* ScenarioTests.h */, 157 | 72EC7E6A17DC505D009AA360 /* ScenarioTests.m */, 158 | 72EC7E4217DC4DCB009AA360 /* NSArray+LinqExtensions.h */, 159 | 72EC7E4417DC4DCB009AA360 /* NSArray+LinqExtensions.m */, 160 | 72EC7E4317DC4DCB009AA360 /* NSDictionary+LinqExtensions.h */, 161 | 72EC7E4517DC4DCB009AA360 /* NSDictionary+LinqExtensions.m */, 162 | 72EC7E3217DC4DA0009AA360 /* Supporting Files */, 163 | ); 164 | path = LinqToObjectiveCTestTests; 165 | sourceTree = ""; 166 | }; 167 | 72EC7E3217DC4DA0009AA360 /* Supporting Files */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 72EC7E3317DC4DA0009AA360 /* LinqToObjectiveCTestTests-Info.plist */, 171 | 72EC7E3417DC4DA0009AA360 /* InfoPlist.strings */, 172 | ); 173 | name = "Supporting Files"; 174 | sourceTree = ""; 175 | }; 176 | /* End PBXGroup section */ 177 | 178 | /* Begin PBXNativeTarget section */ 179 | 72EC7E0817DC4DA0009AA360 /* LinqToObjectiveCTest */ = { 180 | isa = PBXNativeTarget; 181 | buildConfigurationList = 72EC7E3C17DC4DA0009AA360 /* Build configuration list for PBXNativeTarget "LinqToObjectiveCTest" */; 182 | buildPhases = ( 183 | 72EC7E0517DC4DA0009AA360 /* Sources */, 184 | 72EC7E0617DC4DA0009AA360 /* Frameworks */, 185 | 72EC7E0717DC4DA0009AA360 /* Resources */, 186 | ); 187 | buildRules = ( 188 | ); 189 | dependencies = ( 190 | ); 191 | name = LinqToObjectiveCTest; 192 | productName = LinqToObjectiveCTest; 193 | productReference = 72EC7E0917DC4DA0009AA360 /* LinqToObjectiveCTest.app */; 194 | productType = "com.apple.product-type.application"; 195 | }; 196 | 72EC7E2917DC4DA0009AA360 /* LinqToObjectiveCTestTests */ = { 197 | isa = PBXNativeTarget; 198 | buildConfigurationList = 72EC7E3F17DC4DA0009AA360 /* Build configuration list for PBXNativeTarget "LinqToObjectiveCTestTests" */; 199 | buildPhases = ( 200 | 72EC7E2517DC4DA0009AA360 /* Sources */, 201 | 72EC7E2617DC4DA0009AA360 /* Frameworks */, 202 | 72EC7E2717DC4DA0009AA360 /* Resources */, 203 | 72EC7E2817DC4DA0009AA360 /* ShellScript */, 204 | ); 205 | buildRules = ( 206 | ); 207 | dependencies = ( 208 | 72EC7E3017DC4DA0009AA360 /* PBXTargetDependency */, 209 | ); 210 | name = LinqToObjectiveCTestTests; 211 | productName = LinqToObjectiveCTestTests; 212 | productReference = 72EC7E2A17DC4DA0009AA360 /* LinqToObjectiveCTestTests.octest */; 213 | productType = "com.apple.product-type.bundle.ocunit-test"; 214 | }; 215 | /* End PBXNativeTarget section */ 216 | 217 | /* Begin PBXProject section */ 218 | 72EC7E0017DC4DA0009AA360 /* Project object */ = { 219 | isa = PBXProject; 220 | attributes = { 221 | LastUpgradeCheck = 0450; 222 | ORGANIZATIONNAME = "Colin Eberhardt"; 223 | }; 224 | buildConfigurationList = 72EC7E0317DC4DA0009AA360 /* Build configuration list for PBXProject "LinqToObjectiveCTest" */; 225 | compatibilityVersion = "Xcode 3.2"; 226 | developmentRegion = English; 227 | hasScannedForEncodings = 0; 228 | knownRegions = ( 229 | en, 230 | ); 231 | mainGroup = 72EC7DFE17DC4DA0009AA360; 232 | productRefGroup = 72EC7E0A17DC4DA0009AA360 /* Products */; 233 | projectDirPath = ""; 234 | projectRoot = ""; 235 | targets = ( 236 | 72EC7E0817DC4DA0009AA360 /* LinqToObjectiveCTest */, 237 | 72EC7E2917DC4DA0009AA360 /* LinqToObjectiveCTestTests */, 238 | ); 239 | }; 240 | /* End PBXProject section */ 241 | 242 | /* Begin PBXResourcesBuildPhase section */ 243 | 72EC7E0717DC4DA0009AA360 /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | 72EC7E1817DC4DA0009AA360 /* InfoPlist.strings in Resources */, 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | }; 251 | 72EC7E2717DC4DA0009AA360 /* Resources */ = { 252 | isa = PBXResourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | 72EC7E3617DC4DA0009AA360 /* InfoPlist.strings in Resources */, 256 | ); 257 | runOnlyForDeploymentPostprocessing = 0; 258 | }; 259 | /* End PBXResourcesBuildPhase section */ 260 | 261 | /* Begin PBXShellScriptBuildPhase section */ 262 | 72EC7E2817DC4DA0009AA360 /* ShellScript */ = { 263 | isa = PBXShellScriptBuildPhase; 264 | buildActionMask = 2147483647; 265 | files = ( 266 | ); 267 | inputPaths = ( 268 | ); 269 | outputPaths = ( 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | shellPath = /bin/sh; 273 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; 274 | }; 275 | /* End PBXShellScriptBuildPhase section */ 276 | 277 | /* Begin PBXSourcesBuildPhase section */ 278 | 72EC7E0517DC4DA0009AA360 /* Sources */ = { 279 | isa = PBXSourcesBuildPhase; 280 | buildActionMask = 2147483647; 281 | files = ( 282 | 72EC7E1A17DC4DA0009AA360 /* main.m in Sources */, 283 | 72EC7E1E17DC4DA0009AA360 /* AppDelegate.m in Sources */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | 72EC7E2517DC4DA0009AA360 /* Sources */ = { 288 | isa = PBXSourcesBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | 72EC7E4617DC4DCB009AA360 /* NSArray+LinqExtensions.m in Sources */, 292 | 72EC7E4717DC4DCB009AA360 /* NSDictionary+LinqExtensions.m in Sources */, 293 | 72EC7E6B17DC505D009AA360 /* NSArrayLinqExtensionsTest.m in Sources */, 294 | 72EC7E6C17DC505D009AA360 /* NSDictionaryLinqExtensionsTest.m in Sources */, 295 | 72EC7E6D17DC505D009AA360 /* Person.m in Sources */, 296 | 72EC7E6E17DC505D009AA360 /* ScenarioTests.m in Sources */, 297 | 72B9B6761848EA6C0039064C /* MacroTest.m in Sources */, 298 | ); 299 | runOnlyForDeploymentPostprocessing = 0; 300 | }; 301 | /* End PBXSourcesBuildPhase section */ 302 | 303 | /* Begin PBXTargetDependency section */ 304 | 72EC7E3017DC4DA0009AA360 /* PBXTargetDependency */ = { 305 | isa = PBXTargetDependency; 306 | target = 72EC7E0817DC4DA0009AA360 /* LinqToObjectiveCTest */; 307 | targetProxy = 72EC7E2F17DC4DA0009AA360 /* PBXContainerItemProxy */; 308 | }; 309 | /* End PBXTargetDependency section */ 310 | 311 | /* Begin PBXVariantGroup section */ 312 | 72EC7E1617DC4DA0009AA360 /* InfoPlist.strings */ = { 313 | isa = PBXVariantGroup; 314 | children = ( 315 | 72EC7E1717DC4DA0009AA360 /* en */, 316 | ); 317 | name = InfoPlist.strings; 318 | sourceTree = ""; 319 | }; 320 | 72EC7E3417DC4DA0009AA360 /* InfoPlist.strings */ = { 321 | isa = PBXVariantGroup; 322 | children = ( 323 | 72EC7E3517DC4DA0009AA360 /* en */, 324 | ); 325 | name = InfoPlist.strings; 326 | sourceTree = ""; 327 | }; 328 | /* End PBXVariantGroup section */ 329 | 330 | /* Begin XCBuildConfiguration section */ 331 | 72EC7E3A17DC4DA0009AA360 /* Debug */ = { 332 | isa = XCBuildConfiguration; 333 | buildSettings = { 334 | ALWAYS_SEARCH_USER_PATHS = NO; 335 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 336 | CLANG_CXX_LIBRARY = "libc++"; 337 | CLANG_ENABLE_OBJC_ARC = YES; 338 | CLANG_WARN_EMPTY_BODY = YES; 339 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 340 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 341 | COPY_PHASE_STRIP = NO; 342 | GCC_C_LANGUAGE_STANDARD = gnu99; 343 | GCC_DYNAMIC_NO_PIC = NO; 344 | GCC_OPTIMIZATION_LEVEL = 0; 345 | GCC_PREPROCESSOR_DEFINITIONS = ( 346 | "DEBUG=1", 347 | "$(inherited)", 348 | ); 349 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 350 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 351 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 352 | GCC_WARN_UNUSED_VARIABLE = YES; 353 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 354 | SDKROOT = iphoneos; 355 | TARGETED_DEVICE_FAMILY = "1,2"; 356 | }; 357 | name = Debug; 358 | }; 359 | 72EC7E3B17DC4DA0009AA360 /* Release */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ALWAYS_SEARCH_USER_PATHS = NO; 363 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 364 | CLANG_CXX_LIBRARY = "libc++"; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_EMPTY_BODY = YES; 367 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 368 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 369 | COPY_PHASE_STRIP = YES; 370 | GCC_C_LANGUAGE_STANDARD = gnu99; 371 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 372 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 373 | GCC_WARN_UNUSED_VARIABLE = YES; 374 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 375 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 376 | SDKROOT = iphoneos; 377 | TARGETED_DEVICE_FAMILY = "1,2"; 378 | VALIDATE_PRODUCT = YES; 379 | }; 380 | name = Release; 381 | }; 382 | 72EC7E3D17DC4DA0009AA360 /* Debug */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 386 | GCC_PREFIX_HEADER = "LinqToObjectiveCTest/LinqToObjectiveCTest-Prefix.pch"; 387 | INFOPLIST_FILE = "LinqToObjectiveCTest/LinqToObjectiveCTest-Info.plist"; 388 | PRODUCT_NAME = "$(TARGET_NAME)"; 389 | WRAPPER_EXTENSION = app; 390 | }; 391 | name = Debug; 392 | }; 393 | 72EC7E3E17DC4DA0009AA360 /* Release */ = { 394 | isa = XCBuildConfiguration; 395 | buildSettings = { 396 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 397 | GCC_PREFIX_HEADER = "LinqToObjectiveCTest/LinqToObjectiveCTest-Prefix.pch"; 398 | INFOPLIST_FILE = "LinqToObjectiveCTest/LinqToObjectiveCTest-Info.plist"; 399 | PRODUCT_NAME = "$(TARGET_NAME)"; 400 | WRAPPER_EXTENSION = app; 401 | }; 402 | name = Release; 403 | }; 404 | 72EC7E4017DC4DA0009AA360 /* Debug */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinqToObjectiveCTest.app/LinqToObjectiveCTest"; 408 | FRAMEWORK_SEARCH_PATHS = ( 409 | "\"$(SDKROOT)/Developer/Library/Frameworks\"", 410 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", 411 | ); 412 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 413 | GCC_PREFIX_HEADER = "LinqToObjectiveCTest/LinqToObjectiveCTest-Prefix.pch"; 414 | INFOPLIST_FILE = "LinqToObjectiveCTestTests/LinqToObjectiveCTestTests-Info.plist"; 415 | PRODUCT_NAME = "$(TARGET_NAME)"; 416 | TEST_HOST = "$(BUNDLE_LOADER)"; 417 | WRAPPER_EXTENSION = octest; 418 | }; 419 | name = Debug; 420 | }; 421 | 72EC7E4117DC4DA0009AA360 /* Release */ = { 422 | isa = XCBuildConfiguration; 423 | buildSettings = { 424 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LinqToObjectiveCTest.app/LinqToObjectiveCTest"; 425 | FRAMEWORK_SEARCH_PATHS = ( 426 | "\"$(SDKROOT)/Developer/Library/Frameworks\"", 427 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", 428 | ); 429 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 430 | GCC_PREFIX_HEADER = "LinqToObjectiveCTest/LinqToObjectiveCTest-Prefix.pch"; 431 | INFOPLIST_FILE = "LinqToObjectiveCTestTests/LinqToObjectiveCTestTests-Info.plist"; 432 | PRODUCT_NAME = "$(TARGET_NAME)"; 433 | TEST_HOST = "$(BUNDLE_LOADER)"; 434 | WRAPPER_EXTENSION = octest; 435 | }; 436 | name = Release; 437 | }; 438 | /* End XCBuildConfiguration section */ 439 | 440 | /* Begin XCConfigurationList section */ 441 | 72EC7E0317DC4DA0009AA360 /* Build configuration list for PBXProject "LinqToObjectiveCTest" */ = { 442 | isa = XCConfigurationList; 443 | buildConfigurations = ( 444 | 72EC7E3A17DC4DA0009AA360 /* Debug */, 445 | 72EC7E3B17DC4DA0009AA360 /* Release */, 446 | ); 447 | defaultConfigurationIsVisible = 0; 448 | defaultConfigurationName = Release; 449 | }; 450 | 72EC7E3C17DC4DA0009AA360 /* Build configuration list for PBXNativeTarget "LinqToObjectiveCTest" */ = { 451 | isa = XCConfigurationList; 452 | buildConfigurations = ( 453 | 72EC7E3D17DC4DA0009AA360 /* Debug */, 454 | 72EC7E3E17DC4DA0009AA360 /* Release */, 455 | ); 456 | defaultConfigurationIsVisible = 0; 457 | defaultConfigurationName = Release; 458 | }; 459 | 72EC7E3F17DC4DA0009AA360 /* Build configuration list for PBXNativeTarget "LinqToObjectiveCTestTests" */ = { 460 | isa = XCConfigurationList; 461 | buildConfigurations = ( 462 | 72EC7E4017DC4DA0009AA360 /* Debug */, 463 | 72EC7E4117DC4DA0009AA360 /* Release */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | /* End XCConfigurationList section */ 469 | }; 470 | rootObject = 72EC7E0017DC4DA0009AA360 /* Project object */; 471 | } 472 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTest.xcodeproj/project.xcworkspace/xcshareddata/LinqToObjectiveCTest.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | CF04C1DE-70D3-4A38-A59C-A10C3C430343 9 | IDESourceControlProjectName 10 | LinqToObjectiveCTest 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 1003DA7B9190CC7AEB6B44F4E63466C7DC01A5F7 14 | https://github.com/healthjoy-ios-opensource/LinqToObjectiveC.git 15 | 16 | IDESourceControlProjectPath 17 | LinqToObjectiveCTest/LinqToObjectiveCTest.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 1003DA7B9190CC7AEB6B44F4E63466C7DC01A5F7 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/healthjoy-ios-opensource/LinqToObjectiveC.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 1003DA7B9190CC7AEB6B44F4E63466C7DC01A5F7 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 1003DA7B9190CC7AEB6B44F4E63466C7DC01A5F7 36 | IDESourceControlWCCName 37 | LinqToObjectiveC 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTest/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // LinqToObjectiveCTest 4 | // 5 | // Created by Colin Eberhardt on 08/09/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTest/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // LinqToObjectiveCTest 4 | // 5 | // Created by Colin Eberhardt on 08/09/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 16 | // Override point for customization after application launch. 17 | self.window.backgroundColor = [UIColor whiteColor]; 18 | [self.window makeKeyAndVisible]; 19 | return YES; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTest/LinqToObjectiveCTest-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | Eu.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTest/LinqToObjectiveCTest-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'LinqToObjectiveCTest' target in the 'LinqToObjectiveCTest' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iOS SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTest/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTest/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LinqToObjectiveCTest 4 | // 5 | // Created by Colin Eberhardt on 08/09/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/LinqToObjectiveCTestTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.scottlogic.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/MacroTest.h: -------------------------------------------------------------------------------- 1 | // 2 | // MacroTest.h 3 | // LinqToObjectiveCTest 4 | // 5 | // Created by Colin Eberhardt on 29/11/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MacroTest : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/MacroTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // MacroTest.m 3 | // LinqToObjectiveCTest 4 | // 5 | // Created by Colin Eberhardt on 29/11/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import "MacroTest.h" 10 | #import "Person.h" 11 | #import "NSArray+LinqExtensions.h" 12 | 13 | @implementation MacroTest 14 | 15 | - (NSArray*) createTestData 16 | { 17 | return @[[Person personWithName:@"bob" age:@25], 18 | [Person personWithName:@"frank" age:@45], 19 | [Person personWithName:@"ian" age:@35], 20 | [Person personWithName:@"jim" age:@25], 21 | [Person personWithName:@"joe" age:@55]]; 22 | } 23 | 24 | - (void)testSelect 25 | { 26 | NSArray* input = [self createTestData]; 27 | 28 | NSArray* names = [input linq_select:LINQSel(name)]; 29 | 30 | STAssertEquals(names.count, (NSUInteger)5, nil); 31 | // 'spot' check a few values 32 | STAssertEquals(names[0], @"bob", nil); 33 | STAssertEquals(names[4], @"joe", nil); 34 | } 35 | 36 | - (void)testSelectCast 37 | { 38 | NSArray* input = [self createTestData]; 39 | 40 | NSArray* ages = [input linq_select:LINQSelUInt(intAge)]; 41 | 42 | STAssertEquals(ages.count, (NSUInteger)5, nil); 43 | // 'spot' check a few values 44 | STAssertEqualObjects(ages[0], @25, nil); 45 | STAssertEqualObjects(ages[4], @55, nil); 46 | } 47 | 48 | - (void)testSelectViaKey 49 | { 50 | NSArray* input = [self createTestData]; 51 | 52 | NSArray* names = [input linq_select:LINQKey(name)]; 53 | 54 | STAssertEquals(names.count, (NSUInteger)5, nil); 55 | // 'spot' check a few values 56 | STAssertEquals(names[0], @"bob", nil); 57 | STAssertEquals(names[4], @"joe", nil); 58 | } 59 | 60 | - (void)testSelectViaKeyPath 61 | { 62 | NSArray* input = [self createTestData]; 63 | 64 | NSArray* names = [input linq_select:LINQKeyPath(name)]; 65 | 66 | STAssertEquals(names.count, (NSUInteger)5, nil); 67 | // 'spot' check a few values 68 | STAssertEquals(names[0], @"bob", nil); 69 | STAssertEquals(names[4], @"joe", nil); 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/NSArrayLinqExtensionsTest.h: -------------------------------------------------------------------------------- 1 | // 2 | // LinqToObjectiveCTests.h 3 | // LinqToObjectiveCTests 4 | // 5 | // Created by Colin Eberhardt on 02/02/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSArrayLinqExtensionsTest : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/NSArrayLinqExtensionsTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // LinqToObjectiveCTests.m 3 | // LinqToObjectiveCTests 4 | // 5 | // Created by Colin Eberhardt on 02/02/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import "NSArrayLinqExtensionsTest.h" 10 | #import "Person.h" 11 | #import "NSArray+LinqExtensions.h" 12 | 13 | @implementation NSArrayLinqExtensionsTest 14 | 15 | - (NSArray*) createTestData 16 | { 17 | return @[[Person personWithName:@"bob" age:@25], 18 | [Person personWithName:@"frank" age:@45], 19 | [Person personWithName:@"ian" age:@35], 20 | [Person personWithName:@"jim" age:@25], 21 | [Person personWithName:@"joe" age:@55]]; 22 | } 23 | 24 | - (void)testWhere 25 | { 26 | NSArray* input = [self createTestData]; 27 | 28 | NSArray* peopleWhoAre25 = [input linq_where:^BOOL(id person) { 29 | return [[person age] isEqualToNumber:@25]; 30 | }]; 31 | 32 | STAssertEquals(peopleWhoAre25.count, (NSUInteger)2, @"There should have been 2 items returned"); 33 | STAssertEquals([peopleWhoAre25[0] name], @"bob", @"Bob is 25!"); 34 | STAssertEquals([peopleWhoAre25[1] name], @"jim", @"Jim is 25!"); 35 | } 36 | 37 | - (void)testSelect 38 | { 39 | NSArray* input = [self createTestData]; 40 | 41 | NSArray* names = [input linq_select:^id(id person) { 42 | return [person name]; 43 | }]; 44 | 45 | STAssertEquals(names.count, (NSUInteger)5, nil); 46 | // 'spot' check a few values 47 | STAssertEquals(names[0], @"bob", nil); 48 | STAssertEquals(names[4], @"joe", nil); 49 | } 50 | 51 | - (void)testSelectWithNil 52 | { 53 | NSArray* input = [self createTestData]; 54 | 55 | NSArray* names = [input linq_select:^id(id person) { 56 | return [[person name] isEqualToString:@"bob"] ? nil : [person name]; 57 | }]; 58 | 59 | STAssertEquals(names.count, (NSUInteger)5, nil); 60 | // 'spot' check a few values 61 | STAssertEquals(names[0], [NSNull null], nil); 62 | STAssertEquals(names[4], @"joe", nil); 63 | } 64 | 65 | - (void)testSelectAndStopOnNil 66 | { 67 | NSArray* input = [self createTestData]; 68 | 69 | NSArray* names = [input linq_selectAndStopOnNil:^id(id person) { 70 | return [person name]; 71 | }]; 72 | 73 | STAssertEquals(names.count, (NSUInteger)5, nil); 74 | // 'spot' check a few values 75 | STAssertEquals(names[0], @"bob", nil); 76 | STAssertEquals(names[4], @"joe", nil); 77 | } 78 | 79 | - (void)testSelectAndStopOnNilWithNil 80 | { 81 | NSArray* input = [self createTestData]; 82 | 83 | NSArray* names = [input linq_selectAndStopOnNil:^id(id person) { 84 | return [[person name] isEqualToString:@"bob"] ? nil : [person name]; 85 | }]; 86 | 87 | STAssertNil(names, nil); 88 | } 89 | 90 | - (void)testSort 91 | { 92 | NSArray* input = @[@21, @34, @25]; 93 | 94 | NSArray* sortedInput = [input linq_sort]; 95 | 96 | STAssertEquals(sortedInput.count, (NSUInteger)3, nil); 97 | STAssertEqualObjects(sortedInput[0], @21, nil); 98 | STAssertEqualObjects(sortedInput[1], @25, nil); 99 | STAssertEqualObjects(sortedInput[2], @34, nil); 100 | } 101 | 102 | - (void)testSortWithKeySelector 103 | { 104 | NSArray* input = [self createTestData]; 105 | 106 | NSArray* sortedByName = [input linq_sort:LINQKey(name)]; 107 | 108 | STAssertEquals(sortedByName.count, (NSUInteger)5, nil); 109 | STAssertEquals([sortedByName[0] name], @"bob", nil); 110 | STAssertEquals([sortedByName[1] name], @"frank", nil); 111 | STAssertEquals([sortedByName[2] name], @"ian", nil); 112 | STAssertEquals([sortedByName[3] name], @"jim", nil); 113 | STAssertEquals([sortedByName[4] name], @"joe", nil); 114 | } 115 | 116 | - (void)testSortWithKeySelectorWithNil 117 | { 118 | NSArray* input = [self createTestData]; 119 | 120 | NSArray* sortedByName = [input linq_sort:^id(id person) { 121 | return [[person name] isEqualToString:@"bob"] ? nil : [person name]; 122 | 123 | }]; 124 | 125 | STAssertEquals(sortedByName.count, (NSUInteger)5, nil); 126 | STAssertEquals([sortedByName[0] name], @"bob", nil); 127 | STAssertEquals([sortedByName[1] name], @"frank", nil); 128 | STAssertEquals([sortedByName[2] name], @"ian", nil); 129 | STAssertEquals([sortedByName[3] name], @"jim", nil); 130 | STAssertEquals([sortedByName[4] name], @"joe", nil); 131 | } 132 | 133 | - (void)testSortDescending 134 | { 135 | NSArray* input = @[@21, @34, @25]; 136 | 137 | NSArray* sortedDescendingInput = [input linq_sortDescending]; 138 | 139 | STAssertEquals(sortedDescendingInput.count, (NSUInteger)3, nil); 140 | STAssertEqualObjects(sortedDescendingInput[0], @34, nil); 141 | STAssertEqualObjects(sortedDescendingInput[1], @25, nil); 142 | STAssertEqualObjects(sortedDescendingInput[2], @21, nil); 143 | } 144 | 145 | - (void)testSortDescendingWithKeySelector 146 | { 147 | NSArray* input = [self createTestData]; 148 | 149 | NSArray* sortedDescendingByName = [input linq_sortDescending:LINQKey(name)]; 150 | 151 | STAssertEquals(sortedDescendingByName.count, (NSUInteger)5, nil); 152 | STAssertEquals([sortedDescendingByName[0] name], @"joe", nil); 153 | STAssertEquals([sortedDescendingByName[1] name], @"jim", nil); 154 | STAssertEquals([sortedDescendingByName[2] name], @"ian", nil); 155 | STAssertEquals([sortedDescendingByName[3] name], @"frank", nil); 156 | STAssertEquals([sortedDescendingByName[4] name], @"bob", nil); 157 | } 158 | 159 | - (void)testSortDescendingWithKeySelectorWithNil 160 | { 161 | NSArray* input = [self createTestData]; 162 | 163 | NSArray* sortedDescendingByName = [input linq_sortDescending:^id(id person) { 164 | return [[person name] isEqualToString:@"bob"] ? nil : [person name]; 165 | 166 | }]; 167 | 168 | STAssertEquals(sortedDescendingByName.count, (NSUInteger)5, nil); 169 | STAssertEquals([sortedDescendingByName[0] name], @"joe", nil); 170 | STAssertEquals([sortedDescendingByName[1] name], @"jim", nil); 171 | STAssertEquals([sortedDescendingByName[2] name], @"ian", nil); 172 | STAssertEquals([sortedDescendingByName[3] name], @"frank", nil); 173 | STAssertEquals([sortedDescendingByName[4] name], @"bob", nil); 174 | } 175 | 176 | - (void)testOfType 177 | { 178 | NSArray* mixed = @[@"foo", @25, @"bar", @33]; 179 | 180 | NSArray* strings = [mixed linq_ofType:[NSString class]]; 181 | 182 | STAssertEquals(strings.count, (NSUInteger)2, nil); 183 | STAssertEqualObjects(strings[0], @"foo", nil); 184 | STAssertEqualObjects(strings[1], @"bar", nil); 185 | } 186 | 187 | - (void)testSelectMany 188 | { 189 | NSArray* data = @[@"foo, bar", @"fubar"]; 190 | 191 | NSArray* components = [data linq_selectMany:^id(id string) { 192 | return [string componentsSeparatedByString:@", "]; 193 | }]; 194 | 195 | STAssertEquals(components.count, (NSUInteger)3, nil); 196 | STAssertEqualObjects(components[0], @"foo", nil); 197 | STAssertEqualObjects(components[1], @"bar", nil); 198 | STAssertEqualObjects(components[2], @"fubar", nil); 199 | } 200 | 201 | - (void)testDistinctWithKeySelector 202 | { 203 | NSArray* input = [self createTestData]; 204 | 205 | NSArray* peopelWithUniqueAges = [input linq_distinct:LINQKey(age)]; 206 | 207 | STAssertEquals(peopelWithUniqueAges.count, (NSUInteger)4, nil); 208 | STAssertEquals([peopelWithUniqueAges[0] name], @"bob", nil); 209 | STAssertEquals([peopelWithUniqueAges[1] name], @"frank", nil); 210 | STAssertEquals([peopelWithUniqueAges[2] name], @"ian", nil); 211 | STAssertEquals([peopelWithUniqueAges[3] name], @"joe", nil); 212 | } 213 | 214 | - (void)testDistinctWithKeySelectorWithNil 215 | { 216 | NSArray* input = [self createTestData]; 217 | 218 | NSArray* peopelWithUniqueAges = [input linq_distinct:^id(id person) { 219 | return [[person age] isEqualToNumber:@25] ? nil : [person age]; 220 | }]; 221 | 222 | STAssertEquals(peopelWithUniqueAges.count, (NSUInteger)4, nil); 223 | STAssertEquals([peopelWithUniqueAges[0] name], @"bob", nil); 224 | STAssertEquals([peopelWithUniqueAges[1] name], @"frank", nil); 225 | STAssertEquals([peopelWithUniqueAges[2] name], @"ian", nil); 226 | STAssertEquals([peopelWithUniqueAges[3] name], @"joe", nil); 227 | } 228 | 229 | - (void)testDistinct 230 | { 231 | NSArray* names = @[@"bill", @"bob", @"bob", @"brian", @"bob"]; 232 | 233 | NSArray* distinctNames = [names linq_distinct]; 234 | 235 | STAssertEquals(distinctNames.count, (NSUInteger)3, nil); 236 | STAssertEqualObjects(distinctNames[0], @"bill", nil); 237 | STAssertEqualObjects(distinctNames[1], @"bob", nil); 238 | STAssertEqualObjects(distinctNames[2], @"brian", nil); 239 | } 240 | 241 | 242 | - (void)testAggregate 243 | { 244 | NSArray* names = @[@"bill", @"bob", @"brian"]; 245 | 246 | id csv = [names linq_aggregate:^id(id item, id aggregate) { 247 | return [NSString stringWithFormat:@"%@, %@", aggregate, item]; 248 | }]; 249 | 250 | STAssertEqualObjects(csv, @"bill, bob, brian", nil); 251 | 252 | NSArray* numbers = @[@22, @45, @33]; 253 | 254 | id biggestNumber = [numbers linq_aggregate:^id(id item, id aggregate) { 255 | return [item compare:aggregate] == NSOrderedDescending ? item : aggregate; 256 | }]; 257 | 258 | STAssertEqualObjects(biggestNumber, @45, nil); 259 | } 260 | 261 | - (void)testFirstOrNil 262 | { 263 | NSArray* input = [self createTestData]; 264 | NSArray* emptyArray = @[]; 265 | 266 | STAssertNil([emptyArray linq_firstOrNil], nil); 267 | STAssertEquals([[input linq_firstOrNil] name], @"bob", nil); 268 | } 269 | 270 | - (void)testFirtOrNilWithPredicate 271 | { 272 | Person* jimSecond = [Person personWithName:@"jim" age:@22]; 273 | NSMutableArray* input = [NSMutableArray arrayWithArray:[self createTestData]]; 274 | [input addObject:jimSecond]; 275 | 276 | id personJim = [input linq_firstOrNil:^BOOL(Person* person) { 277 | return [person.name isEqualToString:@"jim"] && [person.age isEqualToNumber:@22]; 278 | }]; 279 | 280 | id personSteve = [input linq_firstOrNil:^BOOL(Person* person) { 281 | return [person.name isEqualToString:@"steve"]; 282 | }]; 283 | 284 | STAssertEquals(personJim, jimSecond, @"Returned the wrong Jim!"); 285 | STAssertNil(personSteve, @"Should not have found Steve!"); 286 | STAssertTrue([personJim isKindOfClass:Person.class], @"Should have returned a single object of type Person"); 287 | } 288 | 289 | - (void)testLastOrNil 290 | { 291 | NSArray* input = [self createTestData]; 292 | NSArray* emptyArray = @[]; 293 | 294 | STAssertNil([emptyArray linq_lastOrNil], nil); 295 | STAssertEquals([[input linq_lastOrNil] name], @"joe", nil); 296 | } 297 | 298 | - (void)testTake 299 | { 300 | NSArray* input = [self createTestData]; 301 | 302 | STAssertEquals([input linq_take:0].count, (NSUInteger)0, nil); 303 | STAssertEquals([input linq_take:5].count, (NSUInteger)5, nil); 304 | STAssertEquals([input linq_take:50].count, (NSUInteger)5, nil); 305 | STAssertEquals([[input linq_take:2][0] name], @"bob", nil); 306 | } 307 | 308 | - (void)testSkip 309 | { 310 | NSArray* input = [self createTestData]; 311 | 312 | STAssertEquals([input linq_skip:0].count, (NSUInteger)5, nil); 313 | STAssertEquals([input linq_skip:5].count, (NSUInteger)0, nil); 314 | STAssertEquals([[input linq_skip:2][0] name], @"ian", nil); 315 | } 316 | 317 | 318 | - (void)testAny 319 | { 320 | NSArray* input = @[@25, @44, @36]; 321 | 322 | STAssertFalse([input linq_any:^BOOL(id item) { 323 | return [item isEqualToNumber:@33]; 324 | }], nil); 325 | 326 | STAssertTrue([input linq_any:^BOOL(id item) { 327 | return [item isEqualToNumber:@25]; 328 | }], nil); 329 | } 330 | 331 | - (void)testAll 332 | { 333 | NSArray* input = @[@25, @25, @25]; 334 | 335 | STAssertFalse([input linq_all:^BOOL(id item) { 336 | return [item isEqualToNumber:@33]; 337 | }], nil); 338 | 339 | STAssertTrue([input linq_all:^BOOL(id item) { 340 | return [item isEqualToNumber:@25]; 341 | }], nil); 342 | } 343 | 344 | - (void)testGroupBy 345 | { 346 | NSArray* input = @[@"James", @"Jim", @"Bob"]; 347 | 348 | NSDictionary* groupedByFirstLetter = [input linq_groupBy:^id(id name) { 349 | return [name substringToIndex:1]; 350 | }]; 351 | 352 | STAssertEquals(groupedByFirstLetter.count, (NSUInteger)2, nil); 353 | 354 | // test the group keys 355 | NSArray* keys = [groupedByFirstLetter allKeys]; 356 | STAssertEqualObjects(@"J", keys[0], nil); 357 | STAssertEqualObjects(@"B", keys[1], nil); 358 | 359 | // test that the correct items are in each group 360 | NSArray* groupOne = groupedByFirstLetter[@"J"]; 361 | STAssertEquals(groupOne.count, (NSUInteger)2, nil); 362 | STAssertEqualObjects(@"James", groupOne[0], nil); 363 | STAssertEqualObjects(@"Jim", groupOne[1], nil); 364 | 365 | NSArray* groupTwo = groupedByFirstLetter[@"B"]; 366 | STAssertEquals(groupTwo.count, (NSUInteger)1, nil); 367 | STAssertEqualObjects(@"Bob", groupTwo[0], nil); 368 | } 369 | 370 | - (void)testGroupByWithNil 371 | { 372 | NSArray* input = @[@"James", @"Jim", @"Bob"]; 373 | 374 | NSDictionary* groupedByFirstLetter = [input linq_groupBy:^id(id name) { 375 | NSString* firstChar = [name substringToIndex:1]; 376 | return [firstChar isEqualToString:@"J"] ? nil : firstChar; 377 | }]; 378 | 379 | STAssertEquals(groupedByFirstLetter.count, (NSUInteger)2, nil); 380 | 381 | // test the group keys 382 | NSArray* keys = [groupedByFirstLetter allKeys]; 383 | STAssertEqualObjects([NSNull null], keys[1], nil); 384 | STAssertEqualObjects(@"B", keys[0], nil); 385 | 386 | // test that the correct items are in each group 387 | NSArray* groupOne = groupedByFirstLetter[[NSNull null]]; 388 | STAssertEquals(groupOne.count, (NSUInteger)2, nil); 389 | STAssertEqualObjects(@"James", groupOne[0], nil); 390 | STAssertEqualObjects(@"Jim", groupOne[1], nil); 391 | 392 | NSArray* groupTwo = groupedByFirstLetter[@"B"]; 393 | STAssertEquals(groupTwo.count, (NSUInteger)1, nil); 394 | STAssertEqualObjects(@"Bob", groupTwo[0], nil); 395 | } 396 | 397 | - (void)testToDictionaryWithValueSelector 398 | { 399 | NSArray* input = @[@"James", @"Jim", @"Bob"]; 400 | 401 | NSDictionary* dictionary = [input linq_toDictionaryWithKeySelector:^id(id item) { 402 | return [item substringToIndex:1]; 403 | } valueSelector:^id(id item) { 404 | return [item lowercaseString]; 405 | }]; 406 | 407 | NSLog(@"%@", dictionary); 408 | 409 | // NOTE - two items have the same key, hence the dictionary only has 2 keys 410 | STAssertEquals(dictionary.count, (NSUInteger)2, nil); 411 | 412 | // test the group keys 413 | NSArray* keys = [dictionary allKeys]; 414 | STAssertEqualObjects(@"J", keys[0], nil); 415 | STAssertEqualObjects(@"B", keys[1], nil); 416 | 417 | // test the values 418 | STAssertEqualObjects(dictionary[@"J"], @"jim", nil); 419 | STAssertEqualObjects(dictionary[@"B"], @"bob", nil); 420 | } 421 | 422 | - (void)testToDictionaryWithValueSelectorWithNil 423 | { 424 | NSArray* input = @[@"James", @"Jim", @"Bob"]; 425 | 426 | NSDictionary* dictionary = [input linq_toDictionaryWithKeySelector:^id(id item) { 427 | NSString* firstChar = [item substringToIndex:1]; 428 | return [firstChar isEqualToString:@"J"] ? nil : firstChar; 429 | } valueSelector:^id(id item) { 430 | NSString* lowercaseName = [item lowercaseString]; 431 | return [lowercaseName isEqualToString:@"bob"] ? nil : lowercaseName; 432 | }]; 433 | 434 | NSLog(@"%@", dictionary); 435 | 436 | // NOTE - two items have the same key, hence the dictionary only has 2 keys 437 | STAssertEquals(dictionary.count, (NSUInteger)2, nil); 438 | 439 | // test the group keys 440 | NSArray* keys = [dictionary allKeys]; 441 | STAssertEqualObjects([NSNull null], keys[1], nil); 442 | STAssertEqualObjects(@"B", keys[0], nil); 443 | 444 | // test the values 445 | STAssertEqualObjects(dictionary[[NSNull null]], @"jim", nil); 446 | STAssertEqualObjects(dictionary[@"B"], [NSNull null], nil); 447 | } 448 | 449 | - (void)testToDictionary 450 | { 451 | NSArray* input = @[@"Jim", @"Bob"]; 452 | 453 | NSDictionary* dictionary = [input linq_toDictionaryWithKeySelector:^id(id item) { 454 | return [item substringToIndex:1]; 455 | }]; 456 | 457 | STAssertEquals(dictionary.count, (NSUInteger)2, nil); 458 | 459 | // test the group keys 460 | NSArray* keys = [dictionary allKeys]; 461 | STAssertEqualObjects(@"J", keys[0], nil); 462 | STAssertEqualObjects(@"B", keys[1], nil); 463 | 464 | // test the values 465 | STAssertEqualObjects(dictionary[@"J"], @"Jim", nil); 466 | STAssertEqualObjects(dictionary[@"B"], @"Bob", nil); 467 | } 468 | 469 | 470 | 471 | - (void) testCount 472 | { 473 | NSArray* input = @[@25, @35, @25]; 474 | 475 | NSUInteger numbersEqualTo25 = [input linq_count:^BOOL(id item) { 476 | return [item isEqualToNumber:@25]; 477 | }]; 478 | 479 | STAssertEquals(numbersEqualTo25, (NSUInteger)2, nil); 480 | } 481 | 482 | - (void) testConcat 483 | { 484 | NSArray* input = @[@25, @35]; 485 | 486 | NSArray* result = [input linq_concat:@[@45, @55]]; 487 | 488 | STAssertEquals(result.count, (NSUInteger)4, nil); 489 | STAssertEqualObjects(result[0], @25, nil); 490 | STAssertEqualObjects(result[1], @35, nil); 491 | STAssertEqualObjects(result[2], @45, nil); 492 | STAssertEqualObjects(result[3], @55, nil); 493 | } 494 | 495 | - (void) testReverse 496 | { 497 | NSArray* input = @[@25, @35]; 498 | 499 | NSArray* result = [input linq_reverse]; 500 | 501 | STAssertEquals(result.count, (NSUInteger)2, nil); 502 | STAssertEqualObjects(result[0], @35, nil); 503 | STAssertEqualObjects(result[1], @25, nil); 504 | } 505 | 506 | - (void) testSum 507 | { 508 | NSArray* input = @[@25, @35]; 509 | 510 | NSNumber* sum = [input linq_sum]; 511 | STAssertEqualObjects(sum, @60, nil); 512 | } 513 | 514 | @end 515 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/NSDictionaryLinqExtensionsTest.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionaryLinqExtensionsTest.h 3 | // LinqToObjectiveC 4 | // 5 | // Created by Colin Eberhardt on 26/02/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDictionaryLinqExtensionsTest : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/NSDictionaryLinqExtensionsTest.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionaryLinqExtensionsTest.m 3 | // LinqToObjectiveC 4 | // 5 | // Created by Colin Eberhardt on 26/02/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import "NSDictionaryLinqExtensionsTest.h" 10 | #import "NSDictionary+LinqExtensions.h" 11 | 12 | @implementation NSDictionaryLinqExtensionsTest 13 | 14 | - (void)testWhere 15 | { 16 | NSDictionary* input = @{@"A" : @"Apple", 17 | @"B" : @"Banana", 18 | @"C" : @"Carrot", 19 | @"D" : @"Fish"}; 20 | 21 | 22 | NSDictionary* result = [input linq_where:^BOOL(id key, id value) { 23 | return [key isEqual:[value substringToIndex:1]]; 24 | }]; 25 | 26 | STAssertEquals(result.allKeys.count, (NSUInteger)3, nil); 27 | STAssertEqualObjects(result[@"A"], @"Apple", nil); 28 | STAssertEqualObjects(result[@"B"], @"Banana", nil); 29 | STAssertEqualObjects(result[@"C"], @"Carrot", nil); 30 | } 31 | 32 | - (void)testSelect 33 | { 34 | NSDictionary* input = @{@"A" : @"Apple", 35 | @"B" : @"Banana", 36 | @"C" : @"Carrot", 37 | @"D" : @"Fish"}; 38 | 39 | 40 | NSDictionary* result = [input linq_select:^id(id key, id value) { 41 | return [NSString stringWithFormat:@"%@, %@", key, [value substringToIndex:1]]; 42 | }]; 43 | 44 | STAssertEquals(result.allKeys.count, (NSUInteger)4, nil); 45 | STAssertEqualObjects(result[@"A"], @"A, A", nil); 46 | STAssertEqualObjects(result[@"B"], @"B, B", nil); 47 | STAssertEqualObjects(result[@"C"], @"C, C", nil); 48 | STAssertEqualObjects(result[@"D"], @"D, F", nil); 49 | } 50 | 51 | - (void)testSelectWithNil 52 | { 53 | NSDictionary* input = @{@"A" : @"Apple", 54 | @"B" : @"Banana", 55 | @"C" : @"Carrot", 56 | @"D" : @"Fish"}; 57 | 58 | 59 | NSDictionary* result = [input linq_select:^id(id key, id value) { 60 | NSString* projection = [NSString stringWithFormat:@"%@, %@", key, [value substringToIndex:1]]; 61 | return [projection isEqualToString:@"A, A"] ? nil : projection; 62 | }]; 63 | 64 | STAssertEquals(result.allKeys.count, (NSUInteger)4, nil); 65 | STAssertEqualObjects(result[@"A"], [NSNull null], nil); 66 | STAssertEqualObjects(result[@"B"], @"B, B", nil); 67 | STAssertEqualObjects(result[@"C"], @"C, C", nil); 68 | STAssertEqualObjects(result[@"D"], @"D, F", nil); 69 | } 70 | 71 | - (void)testToArray 72 | { 73 | NSDictionary* input = @{@"A" : @"Apple", 74 | @"B" : @"Banana", 75 | @"C" : @"Carrot"}; 76 | 77 | NSArray* result = [input linq_toArray:^id(id key, id value) { 78 | return [NSString stringWithFormat:@"%@, %@", key, value]; 79 | }]; 80 | 81 | NSLog(@"%@", result); 82 | 83 | STAssertEquals(result.count, (NSUInteger)3, nil); 84 | STAssertEqualObjects(result[0], @"A, Apple", nil); 85 | STAssertEqualObjects(result[1], @"B, Banana", nil); 86 | STAssertEqualObjects(result[2], @"C, Carrot", nil); 87 | } 88 | 89 | - (void)testToArrayWithNil 90 | { 91 | NSDictionary* input = @{@"A" : @"Apple", 92 | @"B" : @"Banana", 93 | @"C" : @"Carrot"}; 94 | 95 | NSArray* result = [input linq_toArray:^id(id key, id value) { 96 | NSString* projection = [NSString stringWithFormat:@"%@, %@", key, value]; 97 | return [projection isEqualToString:@"A, Apple"] ? nil : projection; 98 | }]; 99 | 100 | NSLog(@"%@", result); 101 | 102 | STAssertEquals(result.count, (NSUInteger)3, nil); 103 | STAssertEqualObjects(result[0], [NSNull null], nil); 104 | STAssertEqualObjects(result[1], @"B, Banana", nil); 105 | STAssertEqualObjects(result[2], @"C, Carrot", nil); 106 | } 107 | 108 | - (void)testAll 109 | { 110 | NSDictionary* input = @{@"a" : @"apple", 111 | @"b" : @"banana", 112 | @"c" : @"bat"}; 113 | 114 | BOOL allValuesHaveTheLetterA = [input linq_all:^BOOL(id key, id value) { 115 | return [value rangeOfString:@"a"].length != 0; 116 | }]; 117 | STAssertTrue(allValuesHaveTheLetterA, nil); 118 | 119 | BOOL allValuesContainKey = [input linq_all:^BOOL(id key, id value) { 120 | return [value rangeOfString:key].length != 0; 121 | }]; 122 | STAssertFalse(allValuesContainKey, nil); 123 | } 124 | 125 | - (void)testAny 126 | { 127 | NSDictionary* input = @{@"a" : @"apple", 128 | @"b" : @"banana", 129 | @"c" : @"bat"}; 130 | 131 | BOOL anyValuesHaveTheLetterN = [input linq_any:^BOOL(id key, id value) { 132 | return [value rangeOfString:@"n"].length != 0; 133 | }]; 134 | STAssertTrue(anyValuesHaveTheLetterN, nil); 135 | 136 | BOOL anyKeysHaveTheLetterN = [input linq_any:^BOOL(id key, id value) { 137 | return [key rangeOfString:@"n"].length != 0; 138 | }]; 139 | STAssertFalse(anyKeysHaveTheLetterN, nil); 140 | } 141 | 142 | 143 | - (void)testCount 144 | { 145 | NSDictionary* input = @{@"a" : @"apple", 146 | @"b" : @"banana", 147 | @"c" : @"bat"}; 148 | 149 | 150 | NSUInteger valuesThatContainKey = [input linq_count:^BOOL(id key, id value) { 151 | return [value rangeOfString:key].length != 0; 152 | }]; 153 | STAssertEquals(valuesThatContainKey, (NSUInteger)2, nil); 154 | } 155 | 156 | - (void)testMerge 157 | { 158 | NSDictionary* input = @{@"a" : @"apple", 159 | @"b" : @"banana", 160 | @"c" : @"bat"}; 161 | 162 | NSDictionary* merge = @{@"d" : @"dog", 163 | @"b" : @"box", 164 | @"e" : @"egg"}; 165 | 166 | 167 | NSDictionary* result = [input linq_Merge:merge]; 168 | 169 | STAssertEquals(result.allKeys.count, (NSUInteger)5, nil); 170 | STAssertEqualObjects(result[@"a"], @"apple", nil); 171 | STAssertEqualObjects(result[@"b"], @"banana", nil); 172 | STAssertEqualObjects(result[@"c"], @"bat", nil); 173 | STAssertEqualObjects(result[@"d"], @"dog", nil); 174 | STAssertEqualObjects(result[@"e"], @"egg", nil); 175 | } 176 | 177 | @end 178 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/Person.h: -------------------------------------------------------------------------------- 1 | // 2 | // TestObject.h 3 | // ShinobiControls_Source 4 | // 5 | // Created by Colin Eberhardt on 07/01/2013. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface Person : NSObject 12 | 13 | @property (retain, nonatomic) NSString* name; 14 | @property (retain, nonatomic) NSNumber* age; 15 | @property (assign) NSUInteger* intAge; 16 | 17 | + (Person*) personWithName:(NSString*)name age:(NSNumber*)age; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/Person.m: -------------------------------------------------------------------------------- 1 | // 2 | // TestObject.m 3 | // ShinobiControls_Source 4 | // 5 | // Created by Colin Eberhardt on 07/01/2013. 6 | // 7 | // 8 | 9 | #import "Person.h" 10 | 11 | @implementation Person 12 | 13 | @synthesize name = _name; 14 | @synthesize age = _age; 15 | 16 | + (Person*) personWithName:(NSString *)name age:(NSNumber *)age 17 | { 18 | Person* obj = [[Person alloc] init]; 19 | obj.name = name; 20 | obj.age = age; 21 | obj.intAge = [age integerValue]; 22 | return obj; 23 | } 24 | 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/ScenarioTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // ScenarioTests.h 3 | // LinqToObjectiveC 4 | // 5 | // Created by Colin Eberhardt on 07/03/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | Tests that demonstrate more complex scenarious rather than just test specific methods. 13 | */ 14 | @interface ScenarioTests : SenTestCase 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/ScenarioTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ScenarioTests.m 3 | // LinqToObjectiveC 4 | // 5 | // Created by Colin Eberhardt on 07/03/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import "ScenarioTests.h" 10 | #import "Person.h" 11 | #import "NSDictionary+LinqExtensions.h" 12 | #import "NSArray+LinqExtensions.h" 13 | 14 | 15 | /** 16 | Tests for specific scenarious that I have seen on the internet. 17 | */ 18 | @implementation ScenarioTests 19 | 20 | 21 | - (void)testDictionaryToQuerystring 22 | { 23 | NSDictionary* input = @{@"page" : @"24", 24 | @"lang" : @"en-US", 25 | @"q" : @"how+many+kittens", 26 | @"key" : @"1234"}; 27 | 28 | id result = [[input linq_toArray:^id(id key, id value) { 29 | return [NSString stringWithFormat:@"%@=%@", key, value]; 30 | }] 31 | linq_aggregate:^id(id item, id aggregate) { 32 | return [NSString stringWithFormat:@"%@&%@", item, aggregate]; 33 | }]; 34 | 35 | STAssertEqualObjects(@"page=24&q=how+many+kittens&lang=en-US&key=1234", result, nil); 36 | } 37 | 38 | - (void)testCountingPeopleWithSurnamesStartingWithEachLetter 39 | { 40 | NSArray* people = @[[Person personWithName:@"bob" age:@25], 41 | [Person personWithName:@"frank" age:@45], 42 | [Person personWithName:@"ian" age:@35], 43 | [Person personWithName:@"jim" age:@25], 44 | [Person personWithName:@"joe" age:@55]]; 45 | 46 | id result = [[people linq_groupBy:^id(id person) { 47 | return [[[person name] substringToIndex:1] uppercaseString]; 48 | }] 49 | linq_select:^id(id key, id value) { 50 | return [NSNumber numberWithInt:[value count]]; 51 | }]; 52 | 53 | NSLog(@"%@", result); 54 | } 55 | 56 | - (void)testSO_15375528 57 | { 58 | NSArray *array = @[@{@"groupId" : @"1", @"name" : @"matt"}, 59 | @{@"groupId" : @"2", @"name" : @"john"}, 60 | @{@"groupId" : @"3", @"name" : @"steve"}, 61 | @{@"groupId" : @"4", @"name" : @"alice"}, 62 | @{@"groupId" : @"1", @"name" : @"bill"}, 63 | @{@"groupId" : @"2", @"name" : @"bob"}, 64 | @{@"groupId" : @"3", @"name" : @"jack"}, 65 | @{@"groupId" : @"4", @"name" : @"dan"}, 66 | @{@"groupId" : @"1", @"name" : @"kevin"}, 67 | @{@"groupId" : @"2", @"name" : @"mike"}, 68 | @{@"groupId" : @"3", @"name" : @"daniel"}, 69 | ]; 70 | 71 | NSArray* grouped = [[array linq_groupBy:^id(id app) { 72 | return [app objectForKey:@"groupId"]; 73 | }] linq_toArray:^id(id key, id value) { 74 | int __block index = 0; 75 | id dic = [[value linq_toDictionaryWithKeySelector:^id(id item) { 76 | return [NSString stringWithFormat:@"name%d", index++ + 1]; 77 | } valueSelector:^id(id item) { 78 | return [item objectForKey:@"name"]; 79 | }] 80 | linq_Merge: @{@"groupId" : key}]; 81 | return dic; 82 | }]; 83 | 84 | NSLog(@"%@", grouped);; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /LinqToObjectiveCTest/LinqToObjectiveCTestTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2013 Colin Eberhardt 2 | Linq to Objective-C 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /NSArray+LinqExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+LinqExtensions.h 3 | // LinqToObjectiveC 4 | // 5 | // Created by Colin Eberhardt on 02/02/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | // Selector macros 12 | // Use the cast variants to explicitly box an non object value. 13 | #define LINQSel(__key) (^id(id item){return [item __key];}) 14 | #define LINQSelCast(__cast, __key) (^id(id item){return @( (__cast) [item __key]);}) 15 | #define LINQSelInt(__key) LINQSelCast(NSInteger, __key) 16 | #define LINQSelUInt(__key) LINQSelCast(NSUInteger, __key) 17 | 18 | // Key path selection macros. 19 | // Values obtained via KVC methods are automatically boxed. 20 | #define LINQKeyPath(__keyp) (^id(id item){return [item valueForKeyPath:@#__keyp];}) 21 | #define LINQKey(__key) (^id(id item){return [item valueForKey:@#__key];}) 22 | 23 | typedef BOOL (^LINQCondition)(id item); 24 | 25 | typedef id (^LINQSelector)(id item); 26 | 27 | typedef id (^LINQAccumulator)(id item, id aggregate); 28 | 29 | /** 30 | Various NSArray extensions that provide a Linq-style query API 31 | */ 32 | @interface NSArray (QueryExtension) 33 | 34 | /** Filters a sequence of values based on a predicate. 35 | 36 | @param predicate The function to test each source element for a condition. 37 | @return An array that contains elements from the input sequence that satisfy the condition. 38 | */ 39 | - (NSArray*) linq_where:(LINQCondition)predicate; 40 | 41 | /** Projects each element of a sequence into a new form. 42 | 43 | @param selector A transform function to apply to each element. 44 | @return An array whose elements are the result of invoking the transform function on each element of source. 45 | */ 46 | - (NSArray*) linq_select:(LINQSelector)transform; 47 | 48 | /** Projects each element of a sequence into a new form. If the transform returns nil for any of the elements, 49 | the projection fails and returns nil. 50 | 51 | @param selector A transform function to apply to each element. 52 | @return An array whose elements are the result of invoking the transform function on each element of source. 53 | */ 54 | - (NSArray*)linq_selectAndStopOnNil:(LINQSelector)transform; 55 | 56 | 57 | /** Sorts the elements of a sequence in ascending order. 58 | 59 | @return An array whose elements are sorted in ascending order. 60 | */ 61 | - (NSArray*) linq_sort; 62 | 63 | /** Sorts the elements of a sequence in ascending order by using a specified keySelector. 64 | 65 | @param keySelector A selector that provides the 'key' which the array should by sorted by. 66 | @return An array whose elements are sorted in ascending order. 67 | */ 68 | - (NSArray*) linq_sort:(LINQSelector)keySelector; 69 | 70 | /** Sorts the elements of a sequence in descending order. 71 | 72 | @return An array whose elements are sorted in descending order. 73 | */ 74 | - (NSArray *)linq_sortDescending; 75 | 76 | /** Sorts the elements of a sequence in descending order by using a specified keySelector. 77 | 78 | @param keySelector A selector that provides the 'key' which the array should by sorted by. 79 | @return An array whose elements are sorted in descending order. 80 | */ 81 | - (NSArray *)linq_sortDescending:(LINQSelector)keySelector; 82 | 83 | /** Filters the elements of an an array based on a specified type. 84 | 85 | @param type The type to filter the elements of the sequence on. 86 | @return An array whose elements are all of the given type. 87 | */ 88 | - (NSArray*) linq_ofType:(Class)type; 89 | 90 | /** Projects each element of a sequence to an NSArray and flattens the resulting sequences into one sequence. 91 | 92 | @param transform A transform function to apply to each element, this should return an NSArray. 93 | @return An array whose elements are the result of invoking the one-to-many transform function on each element of the input sequence. 94 | */ 95 | - (NSArray*) linq_selectMany:(LINQSelector)transform; 96 | 97 | /** Returns distinct elements from a sequence. 98 | 99 | @return An array of distinct elements. 100 | */ 101 | - (NSArray*) linq_distinct; 102 | 103 | /** Returns distinct elements from a sequence, where the given selector is used to specify the value to use for equality for each item. 104 | 105 | @param keySelector Specifies the value to use for equality for each item. 106 | @return An array of distinct elements. 107 | */ 108 | - (NSArray*) linq_distinct:(LINQSelector)keySelector; 109 | 110 | /** Applies an accumulator function over a sequence. The item in the array is used as the initial aggregate value. 111 | 112 | @param accumulator An accumulator function to be invoked on each element. 113 | @return The final accumulator value. 114 | */ 115 | - (id) linq_aggregate:(LINQAccumulator)accumulator; 116 | 117 | /** Returns the first item from the source array, or nil if the array is empty. 118 | 119 | @return The first item from the source array, or nil if the array is empty. 120 | */ 121 | - (id) linq_firstOrNil; 122 | 123 | /** Returns the first item from the source array matching a predicate, or nil if there are no objects passing the test. 124 | 125 | @param predicate The function to test each source element for a condition. 126 | @return An item from the input sequence that satisfy the condition. 127 | */ 128 | - (id)linq_firstOrNil:(LINQCondition)predicate; 129 | 130 | /** Returns the last item from the source array, or nil if the array is empty. 131 | 132 | @return The last item from the source array, or nil if the array is empty. 133 | */ 134 | - (id) linq_lastOrNil; 135 | 136 | /** Bypasses a specified number of elements in an array and then returns the remaining elements. 137 | 138 | @param count The number of elements to bypass. 139 | @return An array that contains the elements that occur after the specified index in the input array. 140 | */ 141 | - (NSArray*) linq_skip:(NSUInteger)count; 142 | 143 | /** Returns a specified number of contiguous elements from the start of an array. 144 | 145 | @param count The number of elements to take. 146 | @return An array that contains the specified number of elements from the start of the input array. 147 | */ 148 | - (NSArray*) linq_take:(NSUInteger)count; 149 | 150 | /** Determines whether all the elements of the array satisfies a condition. 151 | 152 | @param condition The condition to test elements against. 153 | @return Whether all the elements of the array satisfies a condition. 154 | */ 155 | - (BOOL) linq_all:(LINQCondition)condition; 156 | 157 | /** Determines whether any of the elements of the array satisfies a condition. 158 | 159 | @param condition The condition to test elements against. 160 | @return Whether any of the elements of the array satisfies a condition. 161 | */ 162 | - (BOOL) linq_any:(LINQCondition)condition; 163 | 164 | /** Groups the elements of the array by keys provided by the given key selector. The returned dictionary will contain the keys that are the result of applying the key selector function to each item of the array, and the value for each key is an array of all the items that return the same key value. 165 | 166 | @param groupKeySelector Determines the group key for each item in the array 167 | @return A dictionary that groups the items via the given key selector. 168 | */ 169 | - (NSDictionary*) linq_groupBy:(LINQSelector)groupKeySelector; 170 | 171 | /** Transforms the source array into a dictionary by applying the given keySelector and valueSelector to each item in the array. 172 | 173 | @param keySelector A selector function that is applied to each item to determine the key it will have within the returned dictionary. 174 | @param valueSelector A selector function that is applied to each item to determine the value it will have within the returned dictionary. 175 | @return A dictionary that is the result of applying the supplied selector functions to each item of the array. 176 | */ 177 | - (NSDictionary*) linq_toDictionaryWithKeySelector:(LINQSelector)keySelector valueSelector:(LINQSelector)valueSelector; 178 | 179 | /** Transforms the source array into a dictionary by applying the given keySelectorto each item in the array. 180 | 181 | @param keySelector A selector function that is applied to each item to determine the key it will have within the returned dictionary. 182 | @return A dictionary that is the result of applying the supplied selector functions to each item of the array. 183 | */ 184 | - (NSDictionary*) linq_toDictionaryWithKeySelector:(LINQSelector)keySelector; 185 | 186 | /** Counts the number of elements in the array that satisfy the given condition. 187 | 188 | @param condition The condition to test elements against. 189 | @return The number of elements that satisfy the condition. 190 | */ 191 | - (NSUInteger) linq_count:(LINQCondition)condition; 192 | 193 | /** Concatonates the given array to the end of this array. 194 | 195 | @param array The array to concatonate. 196 | @return The concatonated array. 197 | */ 198 | - (NSArray*) linq_concat:(NSArray*)array; 199 | 200 | /** Reverses the order of items within this array. 201 | 202 | @return The reversed array. 203 | */ 204 | - (NSArray*) linq_reverse; 205 | 206 | /** Sums the elements in the array. 207 | 208 | @return The sum of elements within this array. 209 | */ 210 | - (NSNumber*)linq_sum; 211 | 212 | @end 213 | -------------------------------------------------------------------------------- /NSArray+LinqExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+LinqExtensions.m 3 | // LinqToObjectiveC 4 | // 5 | // Created by Colin Eberhardt on 02/02/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import "NSArray+LinqExtensions.h" 10 | 11 | @implementation NSArray (QueryExtension) 12 | 13 | - (NSArray *)linq_where:(LINQCondition)predicate 14 | { 15 | NSMutableArray* result = [[NSMutableArray alloc] init]; 16 | for(id item in self) { 17 | if (predicate(item)) { 18 | [result addObject:item]; 19 | } 20 | } 21 | return result; 22 | } 23 | 24 | - (NSArray *)linq_select:(LINQSelector)transform 25 | andStopOnError:(BOOL)shouldStopOnError 26 | { 27 | NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:self.count]; 28 | for(id item in self) 29 | { 30 | id object = transform(item); 31 | if (nil != object) 32 | { 33 | [result addObject: object]; 34 | } 35 | else 36 | { 37 | if (shouldStopOnError) 38 | { 39 | return nil; 40 | } 41 | else 42 | { 43 | [result addObject: [NSNull null]]; 44 | } 45 | } 46 | } 47 | return result; 48 | } 49 | 50 | - (NSArray *)linq_select:(LINQSelector)transform 51 | { 52 | return [self linq_select: transform 53 | andStopOnError: NO]; 54 | } 55 | 56 | - (NSArray*)linq_selectAndStopOnNil:(LINQSelector)transform 57 | { 58 | return [self linq_select: transform 59 | andStopOnError: YES]; 60 | } 61 | 62 | 63 | - (NSArray *)linq_sort:(LINQSelector)keySelector 64 | { 65 | return [self sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 66 | id valueOne = keySelector(obj1); 67 | id valueTwo = keySelector(obj2); 68 | NSComparisonResult result = [valueOne compare:valueTwo]; 69 | return result; 70 | }]; 71 | } 72 | 73 | - (NSArray *)linq_sort 74 | { 75 | return [self linq_sort:^id(id item) { return item;} ]; 76 | } 77 | 78 | - (NSArray *)linq_sortDescending:(LINQSelector)keySelector 79 | { 80 | return [self sortedArrayUsingComparator:^NSComparisonResult(id obj2, id obj1) { 81 | id valueOne = keySelector(obj1); 82 | id valueTwo = keySelector(obj2); 83 | NSComparisonResult result = [valueOne compare:valueTwo]; 84 | return result; 85 | }]; 86 | } 87 | 88 | - (NSArray *)linq_sortDescending 89 | { 90 | return [self linq_sortDescending:^id(id item) { return item;} ]; 91 | } 92 | 93 | - (NSArray *)linq_ofType:(Class)type 94 | { 95 | return [self linq_where:^BOOL(id item) { 96 | return [[item class] isSubclassOfClass:type]; 97 | }]; 98 | } 99 | 100 | - (NSArray *)linq_selectMany:(LINQSelector)transform 101 | { 102 | NSMutableArray* result = [[NSMutableArray alloc] init]; 103 | for(id item in self) { 104 | for(id child in transform(item)){ 105 | [result addObject:child]; 106 | } 107 | } 108 | return result; 109 | } 110 | 111 | - (NSArray *)linq_distinct 112 | { 113 | NSMutableArray* distinctSet = [[NSMutableArray alloc] init]; 114 | for (id item in self) { 115 | if (![distinctSet containsObject:item]) { 116 | [distinctSet addObject:item]; 117 | } 118 | } 119 | return distinctSet; 120 | } 121 | 122 | - (NSArray *)linq_distinct:(LINQSelector)keySelector 123 | { 124 | NSMutableSet* keyValues = [[NSMutableSet alloc] init]; 125 | NSMutableArray* distinctSet = [[NSMutableArray alloc] init]; 126 | for (id item in self) { 127 | id keyForItem = keySelector(item); 128 | if (!keyForItem) 129 | keyForItem = [NSNull null]; 130 | if (![keyValues containsObject:keyForItem]) { 131 | [distinctSet addObject:item]; 132 | [keyValues addObject:keyForItem]; 133 | } 134 | } 135 | return distinctSet; 136 | } 137 | 138 | - (id)linq_aggregate:(LINQAccumulator)accumulator 139 | { 140 | id aggregate = nil; 141 | for (id item in self) { 142 | if (aggregate == nil) { 143 | aggregate = item; 144 | } else { 145 | aggregate = accumulator(item, aggregate); 146 | } 147 | } 148 | return aggregate; 149 | } 150 | 151 | - (id)linq_firstOrNil 152 | { 153 | return self.count == 0 ? nil : [self objectAtIndex:0]; 154 | } 155 | 156 | - (id)linq_firstOrNil:(LINQCondition)predicate 157 | { 158 | for(id item in self) { 159 | if (predicate(item)) { 160 | return item; 161 | } 162 | } 163 | return nil; 164 | } 165 | 166 | - (id)linq_lastOrNil 167 | { 168 | return self.count == 0 ? nil : [self objectAtIndex:self.count - 1]; 169 | } 170 | 171 | - (NSArray*)linq_skip:(NSUInteger)count 172 | { 173 | if (count < self.count) { 174 | NSRange range = {.location = count, .length = self.count - count}; 175 | return [self subarrayWithRange:range]; 176 | } else { 177 | return @[]; 178 | } 179 | } 180 | 181 | - (NSArray*)linq_take:(NSUInteger)count 182 | { 183 | NSRange range = { .location=0, 184 | .length = count > self.count ? self.count : count}; 185 | return [self subarrayWithRange:range]; 186 | } 187 | 188 | - (BOOL)linq_any:(LINQCondition)condition 189 | { 190 | for (id item in self) { 191 | if (condition(item)) { 192 | return YES; 193 | } 194 | } 195 | return NO; 196 | } 197 | 198 | - (BOOL)linq_all:(LINQCondition)condition 199 | { 200 | for (id item in self) { 201 | if (!condition(item)) { 202 | return NO; 203 | } 204 | } 205 | return YES; 206 | } 207 | 208 | - (NSDictionary*)linq_groupBy:(LINQSelector)groupKeySelector 209 | { 210 | NSMutableDictionary* groupedItems = [[NSMutableDictionary alloc] init]; 211 | for (id item in self) { 212 | id key = groupKeySelector(item); 213 | if (!key) 214 | key = [NSNull null]; 215 | NSMutableArray* arrayForKey; 216 | if (!(arrayForKey = [groupedItems objectForKey:key])){ 217 | arrayForKey = [[NSMutableArray alloc] init]; 218 | [groupedItems setObject:arrayForKey forKey:key]; 219 | } 220 | [arrayForKey addObject:item]; 221 | } 222 | return groupedItems; 223 | } 224 | 225 | - (NSDictionary *)linq_toDictionaryWithKeySelector:(LINQSelector)keySelector valueSelector:(LINQSelector)valueSelector 226 | { 227 | NSMutableDictionary* result = [[NSMutableDictionary alloc] init]; 228 | for (id item in self) { 229 | id key = keySelector(item); 230 | id value = valueSelector!=nil ? valueSelector(item) : item; 231 | 232 | if (!key) 233 | key = [NSNull null]; 234 | if (!value) 235 | value = [NSNull null]; 236 | 237 | [result setObject:value forKey:key]; 238 | } 239 | return result; 240 | } 241 | 242 | - (NSDictionary *)linq_toDictionaryWithKeySelector:(LINQSelector)keySelector 243 | { 244 | return [self linq_toDictionaryWithKeySelector:keySelector valueSelector:nil]; 245 | } 246 | 247 | - (NSUInteger)linq_count:(LINQCondition)condition 248 | { 249 | return [self linq_where:condition].count; 250 | } 251 | 252 | - (NSArray *)linq_concat:(NSArray *)array 253 | { 254 | NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:self.count + array.count]; 255 | [result addObjectsFromArray:self]; 256 | [result addObjectsFromArray:array]; 257 | return result; 258 | } 259 | 260 | - (NSArray *)linq_reverse 261 | { 262 | NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:self.count]; 263 | for (id item in [self reverseObjectEnumerator]) { 264 | [result addObject:item]; 265 | } 266 | return result; 267 | } 268 | 269 | - (NSNumber *)linq_sum 270 | { 271 | return [self valueForKeyPath: @"@sum.self"]; 272 | } 273 | 274 | @end 275 | -------------------------------------------------------------------------------- /NSDictionary+LinqExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+LinqExtensions.h 3 | // LinqToObjectiveC 4 | // 5 | // Created by Colin Eberhardt on 25/02/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef id (^LINQKeyValueSelector)(id key, id value); 12 | 13 | typedef BOOL (^LINQKeyValueCondition)(id key, id value); 14 | 15 | /** 16 | Various NSDictionary extensions that provide a Linq-style query API 17 | */ 18 | @interface NSDictionary (QueryExtension) 19 | 20 | /** Filters a dictionary based on a predicate. 21 | 22 | @param predicate The function to test each source key-value pair for a condition. 23 | @return A dictionary that contains key-value pairs from the input dictionary that satisfy the condition. 24 | */ 25 | - (NSDictionary*) linq_where:(LINQKeyValueCondition)predicate; 26 | 27 | /** Projects each element of the dictionary into a new form. 28 | 29 | @param selector A transform function to apply to each element. 30 | @return A dicionary whose elements are the result of invoking the transform function on each key-value pair of source. 31 | */ 32 | - (NSDictionary*) linq_select:(LINQKeyValueSelector)selector; 33 | 34 | /** Projects each element of the dictionary to a new form, which is used to populate the returned array. 35 | 36 | @param selector A transform function to apply to each element. 37 | @return An array whose elements are the result of invoking the transform function on each key-value pair of source. 38 | */ 39 | - (NSArray*) linq_toArray:(LINQKeyValueSelector)selector; 40 | 41 | /** Determines whether all of the key-value pairs of the dictionary satisfies a condition. 42 | 43 | @param condition The condition to test key-value pairs against. 44 | @return Whether any of the element of the dictionary satisfies a condition. 45 | */ 46 | - (BOOL) linq_all:(LINQKeyValueCondition)condition; 47 | 48 | /** Determines whether any of the key-value pairs of the dictionary satisfies a condition. 49 | 50 | @param condition The condition to test key-value pairs against. 51 | @return Whether any of the element of the dictionary satisfies a condition. 52 | */ 53 | - (BOOL) linq_any:(LINQKeyValueCondition)condition; 54 | 55 | /** Counts the number of key-value pairs that satisfy the given condition. 56 | 57 | @param condition The condition to test key-value pairs against. 58 | @return The number of elements that satisfy the condition. 59 | */ 60 | - (NSUInteger) linq_count:(LINQKeyValueCondition)condition; 61 | 62 | /** Merges the contents of this dictionary with the given dictionary. For any duplicates, the value from 63 | the source dictionary will be used. 64 | 65 | @param dic The dictionary to merge with. 66 | @return A dictionary which is the result of merging. 67 | */ 68 | - (NSDictionary*) linq_Merge:(NSDictionary*)dic; 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /NSDictionary+LinqExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+LinqExtensions.m 3 | // LinqToObjectiveC 4 | // 5 | // Created by Colin Eberhardt on 25/02/2013. 6 | // Copyright (c) 2013 Colin Eberhardt. All rights reserved. 7 | // 8 | 9 | #import "NSDictionary+LinqExtensions.h" 10 | 11 | @implementation NSDictionary (QueryExtension) 12 | 13 | - (NSDictionary *)linq_where:(LINQKeyValueCondition)predicate 14 | { 15 | NSMutableDictionary* result = [[NSMutableDictionary alloc] init]; 16 | [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 17 | if (predicate(key, obj)) { 18 | [result setObject:obj forKey:key]; 19 | } 20 | }]; 21 | return result; 22 | } 23 | 24 | - (NSDictionary *)linq_select:(LINQKeyValueSelector)selector 25 | { 26 | NSMutableDictionary* result = [[NSMutableDictionary alloc] init]; 27 | [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 28 | id object = selector(key, obj); 29 | if (!object) 30 | object = [NSNull null]; 31 | 32 | [result setObject:object forKey:key]; 33 | }]; 34 | return result; 35 | } 36 | 37 | - (NSArray *)linq_toArray:(LINQKeyValueSelector)selector 38 | { 39 | NSMutableArray* result = [[NSMutableArray alloc] init]; 40 | [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 41 | id object = selector(key, obj); 42 | if (!object) 43 | object = [NSNull null]; 44 | [result addObject:object]; 45 | }]; 46 | return result; 47 | } 48 | 49 | - (BOOL)linq_all:(LINQKeyValueCondition)condition 50 | { 51 | __block BOOL all = TRUE; 52 | [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 53 | if (!condition(key, obj)){ 54 | all = FALSE; 55 | *stop = TRUE; 56 | } 57 | }]; 58 | return all; 59 | } 60 | 61 | - (BOOL)linq_any:(LINQKeyValueCondition)condition 62 | { 63 | __block BOOL any = FALSE; 64 | [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 65 | if (condition(key, obj)){ 66 | any = TRUE; 67 | *stop = TRUE; 68 | } 69 | }]; 70 | return any; 71 | } 72 | 73 | - (NSUInteger)linq_count:(LINQKeyValueCondition)condition 74 | { 75 | return [self linq_where:condition].count; 76 | } 77 | 78 | - (NSDictionary *)linq_Merge:(NSDictionary *)dictionary 79 | { 80 | NSMutableDictionary* result = [[NSMutableDictionary alloc] initWithDictionary:self]; 81 | [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 82 | if (![result objectForKey:key]) { 83 | [result setObject:obj forKey:key]; 84 | } 85 | }]; 86 | return result; 87 | } 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Linq To Objective-C 2 | 3 | Bringing a Linq-style fluent query API to Objective-C. 4 | 5 | This project contains a collection of `NSArray` and `NSDictionary` methods that allow you to execute queries using a fluent syntax, inspired by [Linq](http://msdn.microsoft.com/en-us/library/vstudio/bb397926.aspx). In order to use *Linq to Objective-C* simply copy the `NSArray+LinqExtensions.h`, `NSArray+LinqExtensions.m`, `NSDictionary+LinqExtensions.h` and `NSDictionary+LinqExtensions.m` files into your project and import the header within any file where you wish to use the API. 6 | 7 | Alternatively, you can include these files via [CocoaPods](http://cocoapods.org/). 8 | 9 | As an example of the types of query this API makes possible, let's say you have an array of `Person` instances, each with a `surname` property. The following query will create a sorted, comma-separated list of the unique surnames from the array: 10 | 11 | ```objc 12 | LINQSelector surnameSelector = ^id(id person){ 13 | return [person name]; 14 | }; 15 | 16 | LINQAccumulator csvAccumulator = ^id(id item, id aggregate) { 17 | return [NSString stringWithFormat:@"%@, %@", aggregate, item]; 18 | }; 19 | 20 | NSArray* surnamesList = [[[[people linq_select:surnameSelector] 21 | linq_sort] 22 | linq_distinct] 23 | linq_aggregate:csvAccumulator]; 24 | ``` 25 | 26 | For a detailed discussion of the history of Linq and why I implemented this API, see the [related blog post](http://www.scottlogic.co.uk/blog/colin/2013/02/linq-to-objective-c/). 27 | 28 | # Licence 29 | 30 | The code within project is made available under the standard MIT licence, see the included licence file. 31 | 32 | # API Overview 33 | 34 | 35 | `NSArray` methods: 36 | 37 | - [linq_where](#where) 38 | - [linq_select](#select) 39 | - [linq_selectAndStopOnNil](#selectAndStopOnNil) 40 | - [linq_sort](#sort) 41 | - [linq_ofType](#ofType) 42 | - [linq_selectMany](#selectMany) 43 | - [linq_distinct](#distinct) 44 | - [linq_aggregate](#aggregate) 45 | - [linq_firstOrNil](#firstOrNil) 46 | - [linq_lastOrNil](#lastOrNil) 47 | - [linq_skip](#skip) 48 | - [linq_take](#take) 49 | - [linq_any](#any) 50 | - [linq_all](#all) 51 | - [linq_groupBy](#groupBy) 52 | - [linq_toDictionary](#toDictionary) 53 | - [linq_count](#count) 54 | - [linq_concat](#concat) 55 | - [linq_reverse](#reverse) 56 | 57 | `NSDictionary` methods: 58 | 59 | - [linq_where](#dictionary-where) 60 | - [linq_select](#dictionary-select) 61 | - [linq_toArray](#dictionary-toArray) 62 | - [linq_any](#dictionary-any) 63 | - [linq_all](#dictionary-all) 64 | - [linq_count](#dictionary-count) 65 | - [linq_merge](#dictionary-merge) 66 | 67 | 68 | ## NSArray methods 69 | 70 | This section provides a few brief examples of each of the API methods. A number of these examples use an array of Person instances: 71 | 72 | ```objc 73 | interface Person : NSObject 74 | 75 | @property (retain, nonatomic) NSString* name; 76 | @property (retain, nonatomic) NSNumber* age; 77 | 78 | @end 79 | ``` 80 | 81 | ### linq_where 82 | 83 | 84 | ```objc 85 | - (NSArray*) linq_where:(LINQCondition)predicate; 86 | ``` 87 | 88 | Filters a sequence of values based on a predicate. 89 | 90 | The following example uses the where method to find people who are 25: 91 | 92 | ```objc 93 | NSArray* peopleWhoAre25 = [input linq_where:^BOOL(id person) { 94 | return [[person age] isEqualToNumber:@25]; 95 | }]; 96 | ``` 97 | 98 | ### linq_select 99 | 100 | ```objc 101 | - (NSArray*) linq_select:(LINQSelector)transform; 102 | ``` 103 | 104 | Projects each element of a sequence into a new form. Each element in the array is transformed by a 'selector' into a new form, which is then used to populate the output array. 105 | 106 | The following example uses a selector that returns the name of each `Person` instance. The output will be an array of `NSString` instances. 107 | 108 | ```objc 109 | NSArray* names = [input linq_select:^id(id person) { 110 | return [person name]; 111 | }]; 112 | ``` 113 | 114 | ### linq_selectAndStopOnNil 115 | 116 | ```objc 117 | - (NSArray*)linq_selectAndStopOnNil:(LINQSelector)transform; 118 | ``` 119 | 120 | Projects each element of a sequence into a new form. If the transform returns nil for any of the elements, the projection fails and returns nil. 121 | 122 | ### linq_sort 123 | 124 | ```objc 125 | - (NSArray*) linq_sort; 126 | - (NSArray*) linq_sort:(LINQSelector)keySelector; 127 | - (NSArray*) linq_sortDescending; 128 | - (NSArray*) linq_sortDescending:(LINQSelector)keySelector; 129 | ``` 130 | 131 | Sorts the elements of an array, either via their 'natural' sort order, or via a `keySelector`. 132 | 133 | As an example of natural sort, the following sorts a collection of `NSNumber` instances: 134 | 135 | ```objc 136 | NSArray* input = @[@21, @34, @25]; 137 | NSArray* sortedInput = [input linq_sort]; // 21, 25, 34 138 | ``` 139 | 140 | In order to sort an array of Person instances, you can use the key selector: 141 | 142 | ```objc 143 | NSArray* sortedByName = [input linq_sort:^id(id person) { 144 | return [person name]; 145 | }]; 146 | ``` 147 | 148 | The accompanying 'descending' methods simply reverse the sort order: 149 | 150 | ```objc 151 | NSArray* input = @[@21, @34, @25]; 152 | NSArray* sortedInput = [input linq_sort]; // 21, 25, 34 153 | NSArray* sortedInput = [input linq_sortDescending]; // 34, 25, 21 154 | ``` 155 | 156 | ### linq_sum 157 | 158 | ```objc 159 | - (NSNumber *)linq_sum; 160 | ``` 161 | 162 | Sums the elements in the array. 163 | 164 | ### linq_ofType 165 | 166 | ```objc 167 | - (NSArray*) linq_ofType:(Class)type; 168 | ``` 169 | 170 | Filters the elements of an an array based on a specified type. 171 | 172 | In the following example a mixed array of `NSString` and `NSNumber` instances is filtered to return just the `NSString` instances: 173 | 174 | ```objc 175 | NSArray* mixed = @[@"foo", @25, @"bar", @33]; 176 | NSArray* strings = [mixed linq_ofType:[NSString class]]; 177 | ``` 178 | 179 | ### linq_selectMany 180 | 181 | ```objc 182 | - (NSArray*) linq_selectMany:(LINQSelector)transform; 183 | ``` 184 | 185 | Projects each element of a sequence to an `NSArray` and flattens the resulting sequences into one sequence. 186 | 187 | This is an interesting one! This is similar to the `select` method, however the selector must return an `NSArray`, with the select-many operation flattening the returned arrays into a single sequence. 188 | 189 | Here's a quick example: 190 | 191 | ```objc 192 | NSArray* data = @[@"foo, bar", @"fubar"]; 193 | 194 | NSArray* components = [data linq_selectMany:^id(id string) { 195 | return [string componentsSeparatedByString:@", "]; 196 | }]; 197 | ``` 198 | 199 | A more useful example might use select-many to return all the order-lines for an array of orders. 200 | 201 | ### linq_distinct 202 | 203 | ```objc 204 | - (NSArray*) linq_distinct; 205 | - (NSArray*) linq_distinct:(LINQSelector)keySelector; 206 | ``` 207 | 208 | Returns distinct elements from a sequence. This simply takes an array of items, returning an array of the distinct (i.e. unique) values in source order. 209 | 210 | The no-arg version of this method uses the default method of comparing the given objects. The version that takes a key-selector allows you to specify the value to use for equality for each item. 211 | 212 | Here's an example that returns the distinct values from an array of strings: 213 | 214 | ```objc 215 | NSArray* names = @[@"bill", @"bob", @"bob", @"brian", @"bob"]; 216 | NSArray* distinctNames = [names linq_distinct]; 217 | // returns bill, bob and brian 218 | ``` 219 | 220 | Here's a more complex example that uses the key selector to find people instances with distinct ages: 221 | 222 | ```objc 223 | NSArray* peopleWithUniqueAges = [input linq_distinct:^id(id person) { 224 | return [person age]; 225 | }]; 226 | ``` 227 | 228 | ### linq_aggregate 229 | 230 | ```objc 231 | - (id) linq_aggregate:(LINQAccumulator)accumulator; 232 | ``` 233 | 234 | Applies an accumulator function over a sequence. This method transforms an array into a single value by applying an accumulator function to each successive element. 235 | 236 | Here's an example that creates a comma separated list from an array of strings: 237 | 238 | ```objc 239 | NSArray* names = @[@"bill", @"bob", @"brian"]; 240 | 241 | id aggregate = [names linq_aggregate:^id(id item, id aggregate) { 242 | return [NSString stringWithFormat:@"%@, %@", aggregate, item]; 243 | }]; 244 | // returns "bill, bob, brian" 245 | ``` 246 | 247 | Here's another example that returns the largest value from an array of numbers: 248 | 249 | ```objc 250 | NSArray* numbers = @[@22, @45, @33]; 251 | 252 | id biggestNumber = [numbers linq_aggregate:^id(id item, id aggregate) { 253 | return [item compare:aggregate] == NSOrderedDescending ? item : aggregate; 254 | }]; 255 | // returns 45 256 | ``` 257 | 258 | ### linq_firstOrNil 259 | 260 | ```objc 261 | - (id) linq_firstOrNil; 262 | - (id) linq_firstOrNil:(LINQCondition)predicate; 263 | ``` 264 | 265 | Returns the first element of an array, or nil if the array is empty. 266 | 267 | ### linq_lastOrNil 268 | 269 | ```objc 270 | - (id) linq_lastOrNil; 271 | ``` 272 | 273 | Returns the last element of an array, or nil if the array is empty 274 | 275 | ### linq_skip 276 | 277 | ```objc 278 | - (NSArray*) linq_skip:(NSUInteger)count; 279 | ``` 280 | 281 | Returns an array that skips the first 'n' elements of the source array, including the rest. 282 | 283 | ### linq_take 284 | 285 | ```objc 286 | - (NSArray*) linq_take:(NSUInteger)count; 287 | ``` 288 | 289 | Returns an array that contains the first 'n' elements of the source array. 290 | 291 | ### linq_any 292 | 293 | ```objc 294 | - (BOOL) linq_any:(LINQCondition)condition; 295 | ``` 296 | 297 | Tests whether any item in the array passes the given condition. 298 | 299 | As an example, you can check whether any number in an array is equal to 25: 300 | 301 | ```objc 302 | NSArray* input = @[@25, @44, @36]; 303 | BOOL isAnyEqual = [input linq_any:^BOOL(id item) { 304 | return [item isEqualToNumber:@25]; 305 | }]; 306 | // returns YES 307 | ``` 308 | 309 | ### linq_all 310 | 311 | ```objc 312 | - (BOOL) linq_all:(LINQCondition)condition; 313 | ``` 314 | 315 | Tests whether all the items in the array pass the given condition. 316 | 317 | As an example, you can check whether all the numbers in an array are equal to 25: 318 | 319 | ```objc 320 | NSArray* input = @[@25, @44, @36]; 321 | BOOL areAllEqual = [input linq_all:^BOOL(id item) { 322 | return [item isEqualToNumber:@25]; 323 | }]; 324 | // returns NO 325 | ``` 326 | 327 | ### linq_groupBy 328 | 329 | ```objc 330 | - (NSDictionary*) linq_groupBy:(LINQSelector)groupKeySelector; 331 | ``` 332 | 333 | Groups the items in an array returning a dictionary. The `groupKeySelector` is applied to each element in the array to determine which group it belongs to. 334 | 335 | The returned dictionary has the group values (as returned by the key selector) as its keys, with an `NSArray` for each value, containing all the items within that group. 336 | 337 | As an example, if you wanted to group a number of strings by their first letter, you could do the following: 338 | 339 | ```objc 340 | NSArray* input = @[@"James", @"Jim", @"Bob"]; 341 | 342 | NSDictionary* groupedByFirstLetter = [input linq_groupBy:^id(id name) { 343 | return [name substringToIndex:1]; 344 | }]; 345 | // the returned dictionary is as follows: 346 | // { 347 | // J = ("James", "Jim"); 348 | // B = ("Bob"); 349 | // } 350 | ``` 351 | 352 | ### linq_toDictionary 353 | 354 | ```objc 355 | - (NSDictionary*) linq_toDictionaryWithKeySelector:(LINQSelector)keySelector; 356 | - (NSDictionary*) linq_toDictionaryWithKeySelector:(LINQSelector)keySelector valueSelector:(LINQSelector)valueSelector; 357 | ``` 358 | 359 | Transforms the source array into a dictionary by applying the given keySelector and (optional) valueSelector to each item in the array. If you use the `toDictionaryWithKeySelector:` method, or the `toDictionaryWithKeySelector:valueSelector:` method with a `nil` valueSelector, the value for each dictionary item is simply the item from the source array. 360 | 361 | As an example, the following code takes an array of names, creating a dictionary where the key is the first letter of each name and the value is the name (in lower case). 362 | 363 | ```objc 364 | NSArray* input = @[@"Frank", @"Jim", @"Bob"]; 365 | 366 | NSDictionary* dictionary = [input linq_toDictionaryWithKeySelector:^id(id item) { 367 | return [item substringToIndex:1]; 368 | } valueSelector:^id(id item) { 369 | return [item lowercaseString]; 370 | }]; 371 | 372 | // result: 373 | // ( 374 | // F = frank; 375 | // J = jim; 376 | // B = bob; 377 | // ) 378 | ``` 379 | 380 | Whereas in the following there is no value selector, so the strings from the source array are used directly. 381 | 382 | ```objc 383 | NSArray* input = @[@"Frank", @"Jim", @"Bob"]; 384 | 385 | NSDictionary* dictionary = [input linq_toDictionaryWithKeySelector:^id(id item) { 386 | return [item substringToIndex:1]; 387 | }]; 388 | 389 | // result: 390 | // ( 391 | // F = Frank; 392 | // J = Jim; 393 | // B = Bob; 394 | // ) 395 | ``` 396 | 397 | ### linq_count 398 | 399 | ```objc 400 | - (NSUInteger) linq_count:(LINQCondition)condition; 401 | ``` 402 | 403 | Counts the number of elements in an array that pass a given condition. 404 | 405 | As an example, you can check how many numbers equal a certain value: 406 | 407 | ```objc 408 | NSArray* input = @[@25, @35, @25]; 409 | 410 | NSUInteger numbersEqualTo25 = [input linq_count:^BOOL(id item) { 411 | return [item isEqualToNumber:@25]; 412 | }]; 413 | // returns 2 414 | ``` 415 | 416 | ### linq_concat 417 | 418 | ```objc 419 | - (NSArray*) linq_concat:(NSArray*)array; 420 | ``` 421 | 422 | Returns an array which is the result of concatonating the given array to the end of this array. 423 | 424 | ### linq_reverse 425 | 426 | ```objc 427 | - (NSArray*) linq_reverse; 428 | ``` 429 | 430 | Returns an array that has the same elements as the source but in reverse order. 431 | 432 | ## NSDictionary methods 433 | 434 | This section provides a few brief examples of each of the API methods. 435 | 436 | ### linq_where 437 | 438 | 439 | ```objc 440 | - (NSDictionary*) linq_where:(LINQKeyValueCondition)predicate; 441 | ``` 442 | 443 | Filters a dictionary based on a predicate. 444 | 445 | The following example uses filters a dictionary to remove any keys that are equal to their value. 446 | 447 | ```objc 448 | NSDictionary* result = [input linq_where:^BOOL(id key, id value) { 449 | return [key isEqual:value]; 450 | }]; 451 | ``` 452 | 453 | ### linq_select 454 | 455 | ```objc 456 | - (NSDictionary*) linq_select:(LINQKeyValueConditionKeyValueSelector)selector; 457 | ``` 458 | 459 | Projects each key-value pair in a dictionary into a new form. Each key-value pair is transformed by a 'selector' into a new form, which is then used to populate the values of the output dictionary. 460 | 461 | The following example takes a dictionary which has string values, returning a new dictionary where each value is the first character of the source string. 462 | 463 | ```objc 464 | NSDictionary* result = [input linq_select:^id(id key, id value) { 465 | return [value substringToIndex:1]; 466 | }]; 467 | ``` 468 | 469 | ### linq_toArray 470 | 471 | ```objc 472 | - (NSArray*) linq_toArray:(LINQKeyValueSelector)selector; 473 | ``` 474 | 475 | Projects each key-value pair in a dictionary into a new form, which is used to populate the output array. 476 | 477 | The following example takes a dictionary which has string values, returning an array which concatenates the key and value for each item in the dictionary. 478 | 479 | ```objc 480 | NSDictionary* input = @{@"A" : @"Apple", @"B" : @"Banana", @"C" : @"Carrot"}; 481 | 482 | NSArray* result = [input linq_toArray:^id(id key, id value) { 483 | return [NSString stringWithFormat:@"%@, %@", key, value]; 484 | }]; 485 | 486 | // result: 487 | // ( 488 | // "A, Apple", 489 | // "B, Banana", 490 | // "C, Carrot" 491 | // ) 492 | ``` 493 | 494 | ### linq_any 495 | 496 | ```objc 497 | - (BOOL) linq_any:(LINQKeyValueCondition)condition; 498 | ``` 499 | 500 | Tests whether any key-value pair in the dictionary passes the given condition. 501 | 502 | As an example, you can check whether value contains the letter 'n': 503 | 504 | ```objc 505 | NSDictionary* input = @{@"a" : @"apple", @"b" : @"banana", @"c" : @"bat"}; 506 | 507 | BOOL anyValuesHaveTheLetterN = [input linq_any:^BOOL(id key, id value) { 508 | return [value rangeOfString:@"n"].length != 0; 509 | }]; 510 | // returns YES 511 | ``` 512 | 513 | ### linq_all 514 | 515 | ```objc 516 | - (BOOL) linq_all:(LINQKeyValueCondition)condition; 517 | ``` 518 | 519 | Tests whether all the key-value pairs in the dictionary pass the given condition. 520 | 521 | As an example, you can check whether all values contains the letter 'a', or use the key component of the condition to see if each value contains the string key: 522 | 523 | ```objc 524 | NSDictionary* input = @{@"a" : @"apple", @"b" : @"banana", @"c" : @"bat"}; 525 | 526 | BOOL allValuesHaveTheLetterA = [input linq_all:^BOOL(id key, id value) { 527 | return [value rangeOfString:@"a"].length != 0; 528 | }]; 529 | // returns YES 530 | 531 | BOOL allValuesContainKey = [input linq_all:^BOOL(id key, id value) { 532 | return [value rangeOfString:key].length != 0; 533 | }]; 534 | // returns NO - the value 'bat' does not contain the letter it is keyed with 'c' 535 | ``` 536 | 537 | ### linq_count 538 | 539 | ```objc 540 | - (NSUInteger) linq_count:(LINQKeyValueCondition)condition; 541 | ``` 542 | 543 | Counts the number of key-value pairs that satisfy the given condition. 544 | 545 | The following example counts how many dictionary values contain the key: 546 | 547 | ```objc 548 | NSDictionary* input = @{@"a" : @"apple", @"b" : @"banana", @"c" : @"bat"}; 549 | 550 | 551 | NSUInteger valuesThatContainKey = [input linq_count:^BOOL(id key, id value) { 552 | return [value rangeOfString:key].length != 0; 553 | }]; 554 | // returns 2 - "bat" does not contain the key "c" 555 | ``` 556 | 557 | ### linq_merge 558 | 559 | ```objc 560 | - (NSDictionary*) linq_merge:(NSDictionary*)dic; 561 | ``` 562 | 563 | Merges the contents of this dictionary with the given dictionary. For any duplicates, the value from the source dictionary will be used. 564 | 565 | 566 | The following example merges a pair of dictionaries 567 | 568 | ```objc 569 | NSDictionary* input = @{@"a" : @"apple", @"b" : @"banana", @"c" : @"cat"}; 570 | 571 | NSDictionary* result = [input linq_merge:@{@"d" : @"dog", @"e" : @"elephant"}]; 572 | 573 | // result: 574 | // ( 575 | // a = apple; 576 | // b = banana; 577 | // c = cat; 578 | // d = dog; 579 | // e = elephant; 580 | // ) 581 | ``` 582 | --------------------------------------------------------------------------------