├── .clang-format
├── .gitignore
├── .hgignore
├── .travis.yml
├── BUILD
├── CONTRIBUTING.md
├── FBLFunctional.h
├── FBLFunctional.xcodeproj
├── FBLFunctionalTests_Info.plist
├── FBLFunctional_Info.plist
├── project.pbxproj
└── xcshareddata
│ └── xcschemes
│ └── FBLFunctional.xcscheme
├── FunctionalObjC.podspec
├── LICENSE
├── Package.swift
├── README.md
├── Sources
└── FBLFunctional
│ ├── NSDictionary+FBLFunctional.m
│ ├── NSObject+FBLFunctional.m
│ └── include
│ ├── FBLFunctional.h
│ ├── NSArray+FBLFunctional.h
│ ├── NSDictionary+FBLFunctional.h
│ ├── NSOrderedSet+FBLFunctional.h
│ ├── NSSet+FBLFunctional.h
│ ├── framework.modulemap
│ └── module.modulemap
├── Tests
└── FBLFunctionalTests
│ ├── NSArray+FBLFunctionalTests.m
│ ├── NSDictionary+FBLFunctionalTests.m
│ ├── NSOrderedSet+FBLFunctionalTests.m
│ └── NSSet+FBLFunctionalTests.m
└── WORKSPACE
/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: Google
2 |
3 | AlignOperands: false
4 | AllowShortIfStatementsOnASingleLine: true
5 | AllowShortLoopsOnASingleLine: false
6 | BreakBeforeTernaryOperators: false
7 | ColumnLimit: 100
8 | PointerBindsToType: false
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Generic build products
2 |
3 | *.[oa]
4 | [Bb]uild/
5 | [Pp]re-[Bb]uild/
6 | [Dd]eliverables/
7 | [Dd]istribution/
8 | [Dd]ocumentation/
9 | [Dd]ocs/
10 |
11 | # Swift PM
12 |
13 | Packages/
14 | .build/
15 | *.resolved
16 |
17 | # Bazel
18 |
19 | bazel-*
20 |
21 | # Other VCS
22 |
23 | .hg
24 | .svn
25 | *.prej
26 | *.mine
27 | CVS
28 |
29 | # OSX
30 |
31 | .DS_Store
32 | .DS_Store?
33 | ._*
34 | .~*
35 | ~$*
36 | *.lock
37 | .AppleDouble
38 | .LSOverride
39 | .DocumentRevisions-V100
40 | .fseventsd
41 | .Spotlight-V100
42 | .TemporaryItems
43 | .Trashes
44 | ehthumbs.db
45 | Thumbs.db
46 | .AppleDB
47 | .AppleDesktop
48 | .apdisk
49 |
50 | # Windows
51 |
52 | Thumbs.db
53 | ehthumbs.db
54 | Desktop.ini
55 | $RECYCLE.BIN/
56 | *.cab
57 | *.msi
58 | *.msm
59 | *.msp
60 | *.lnk
61 |
62 | # Xcode
63 |
64 | DerivedData/
65 | xcuserdata/
66 | project.xcworkspace/
67 | *.mode1
68 | *.mode1v3
69 | *.mode2v3
70 | *.perspective
71 | *.perspectivev3
72 | *.pbxuser
73 | *.xccheckout
74 | *.moved-aside
75 | *.xcuserstate
76 | *.xctimeline
77 |
78 | # JetBrains
79 |
80 | .idea/
81 |
82 | # CocoaPods
83 |
84 | !Podfile.lock
85 | !Pods/Manifest.lock
86 | Pods/Documentation
87 |
88 | #Carthage
89 |
90 | Carthage/
91 |
92 | # SublimeText
93 |
94 | *.tmlanguage.cache
95 | *.tmPreferences.cache
96 | *.stTheme.cache
97 | *.sublime-workspace
98 |
--------------------------------------------------------------------------------
/.hgignore:
--------------------------------------------------------------------------------
1 | syntax: glob
2 |
3 | # Generic build products
4 |
5 | *.[oa]
6 | [Bb]uild/
7 | [Pp]re-[Bb]uild/
8 | [Dd]eliverables/
9 | [Dd]istribution/
10 | [Dd]ocumentation/
11 | [Dd]ocs/
12 |
13 | # Swift PM
14 |
15 | Packages/
16 | .build/
17 | *.resolved
18 |
19 | # Bazel
20 |
21 | bazel-*
22 |
23 | # Other VCS
24 |
25 | .hg
26 | .svn
27 | *.prej
28 | *.mine
29 | CVS
30 |
31 | # OSX
32 |
33 | .DS_Store
34 | .DS_Store?
35 | ._*
36 | .~*
37 | ~$*
38 | *.lock
39 | .AppleDouble
40 | .LSOverride
41 | .DocumentRevisions-V100
42 | .fseventsd
43 | .Spotlight-V100
44 | .TemporaryItems
45 | .Trashes
46 | ehthumbs.db
47 | Thumbs.db
48 | .AppleDB
49 | .AppleDesktop
50 | .apdisk
51 |
52 | # Windows
53 |
54 | Thumbs.db
55 | ehthumbs.db
56 | Desktop.ini
57 | $RECYCLE.BIN/
58 | *.cab
59 | *.msi
60 | *.msm
61 | *.msp
62 | *.lnk
63 |
64 | # Xcode
65 |
66 | DerivedData/
67 | xcuserdata/
68 | project.xcworkspace/
69 | *.mode1
70 | *.mode1v3
71 | *.mode2v3
72 | *.perspective
73 | *.perspectivev3
74 | *.pbxuser
75 | *.xccheckout
76 | *.moved-aside
77 | *.xcuserstate
78 | *.xctimeline
79 |
80 | # JetBrains
81 |
82 | .idea/
83 |
84 | # CocoaPods
85 |
86 | !Podfile.lock
87 | !Pods/Manifest.lock
88 | Pods/Documentation
89 |
90 | #Carthage
91 |
92 | Carthage/
93 |
94 | # SublimeText
95 |
96 | *.tmlanguage.cache
97 | *.tmPreferences.cache
98 | *.stTheme.cache
99 | *.sublime-workspace
100 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | os: osx
2 | language: objective-c
3 | install: true
4 | before_install:
5 | - brew update
6 | - brew install bazel
7 | script:
8 | - bazel --batch test Tests --spawn_strategy=standalone --genrule_strategy=standalone --test_strategy=standalone --noshow_progress --noshow_loading_progress --verbose_failures --test_verbose_timeout_warnings --test_output=errors
9 |
--------------------------------------------------------------------------------
/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//visibility:public"])
2 |
3 | licenses(["notice"]) # Apache 2.0
4 |
5 | exports_files(["LICENSE"])
6 |
7 | load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
8 |
9 | OBJC_COPTS = [
10 | "-Wall",
11 | "-Wextra",
12 | "-Werror",
13 | ]
14 |
15 | objc_library(
16 | name = "FBLFunctional",
17 | srcs = glob([
18 | "Sources/FBLFunctional/*.m",
19 | ]),
20 | hdrs = glob([
21 | "Sources/FBLFunctional/include/*.h",
22 | ]) + [
23 | "FBLFunctional.h",
24 | ],
25 | copts = OBJC_COPTS,
26 | includes = [
27 | "Sources/FBLFunctional/include",
28 | ],
29 | )
30 |
31 | ios_unit_test(
32 | name = "Tests",
33 | minimum_os_version = "8.0",
34 | deps = [
35 | ":FBLFunctionalTests",
36 | ],
37 | )
38 |
39 | objc_library(
40 | name = "FBLFunctionalTests",
41 | testonly = 1,
42 | srcs = glob([
43 | "Tests/FBLFunctionalTests/*.m",
44 | ]),
45 | copts = OBJC_COPTS,
46 | deps = [
47 | ":FBLFunctional",
48 | ],
49 | )
50 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute #
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few guidelines you need to follow.
5 |
6 |
7 | ## Contributor License Agreement ##
8 |
9 | Contributions to any Google project must be accompanied by a Contributor
10 | License Agreement. This is not a copyright **assignment**, it simply gives
11 | Google permission to use and redistribute your contributions as part of the
12 | project.
13 |
14 | * If you are an individual writing original source code and you're sure you
15 | own the intellectual property, then you'll need to sign an [individual
16 | CLA][].
17 |
18 | * If you work for a company that wants to allow you to contribute your work,
19 | then you'll need to sign a [corporate CLA][].
20 |
21 | You generally only need to submit a CLA once, so if you've already submitted
22 | one (even if it was for a different project), you probably don't need to do it
23 | again.
24 |
25 | [individual CLA]: https://developers.google.com/open-source/cla/individual
26 | [corporate CLA]: https://developers.google.com/open-source/cla/corporate
27 |
28 |
29 | ## Submitting a patch ##
30 |
31 | 1. It's generally best to start by opening a new issue describing the bug or
32 | feature you're intending to fix. Even if you think it's relatively minor,
33 | it's helpful to know what people are working on. Mention in the initial
34 | issue that you are planning to work on that bug or feature so that it can
35 | be assigned to you.
36 |
37 | 1. Follow the normal process of [forking][] the project, and setup a new
38 | branch to work in. It's important that each group of changes be done in
39 | separate branches in order to ensure that a pull request only includes the
40 | commits related to that bug or feature.
41 |
42 | 1. Any significant changes should almost always be accompanied by tests. The
43 | project already has good test coverage, so look at some of the existing
44 | tests if you're unsure how to go about it.
45 |
46 | 1. Do your best to have [well-formed commit messages][] for each change.
47 | This provides consistency throughout the project, and ensures that commit
48 | messages are able to be formatted properly by various git tools.
49 |
50 | 1. Finally, push the commits to your fork and submit a [pull request][].
51 |
52 | [forking]: https://help.github.com/articles/fork-a-repo
53 | [well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
54 | [pull request]: https://help.github.com/articles/creating-a-pull-request
55 |
--------------------------------------------------------------------------------
/FBLFunctional.h:
--------------------------------------------------------------------------------
1 | Sources/FBLFunctional/include/FBLFunctional.h
--------------------------------------------------------------------------------
/FBLFunctional.xcodeproj/FBLFunctionalTests_Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundleDevelopmentRegion
5 | en
6 | CFBundleExecutable
7 | $(EXECUTABLE_NAME)
8 | CFBundleIdentifier
9 | com.google.$(PRODUCT_BUNDLE_IDENTIFIER)
10 | CFBundleInfoDictionaryVersion
11 | 6.0
12 | CFBundleName
13 | $(PRODUCT_NAME)
14 | CFBundlePackageType
15 | BNDL
16 | CFBundleShortVersionString
17 | 1.0
18 | CFBundleSignature
19 | ????
20 | CFBundleVersion
21 | $(CURRENT_PROJECT_VERSION)
22 | NSPrincipalClass
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/FBLFunctional.xcodeproj/FBLFunctional_Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundleDevelopmentRegion
5 | en
6 | CFBundleExecutable
7 | $(EXECUTABLE_NAME)
8 | CFBundleIdentifier
9 | com.google.$(PRODUCT_BUNDLE_IDENTIFIER)
10 | CFBundleInfoDictionaryVersion
11 | 6.0
12 | CFBundleName
13 | $(PRODUCT_NAME)
14 | CFBundlePackageType
15 | FMWK
16 | CFBundleShortVersionString
17 | 1.0
18 | CFBundleSignature
19 | ????
20 | CFBundleVersion
21 | $(CURRENT_PROJECT_VERSION)
22 | NSPrincipalClass
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/FBLFunctional.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 032B8165204629650097BF12 /* NSDictionary+FBLFunctional.h in Headers */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* NSDictionary+FBLFunctional.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 032B8166204629650097BF12 /* NSOrderedSet+FBLFunctional.h in Headers */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* NSOrderedSet+FBLFunctional.h */; settings = {ATTRIBUTES = (Public, ); }; };
12 | 032B8167204629650097BF12 /* NSArray+FBLFunctional.h in Headers */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* NSArray+FBLFunctional.h */; settings = {ATTRIBUTES = (Public, ); }; };
13 | 032B8168204629650097BF12 /* FBLFunctional.h in Headers */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* FBLFunctional.h */; settings = {ATTRIBUTES = (Public, ); }; };
14 | 032B8169204629650097BF12 /* NSSet+FBLFunctional.h in Headers */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* NSSet+FBLFunctional.h */; settings = {ATTRIBUTES = (Public, ); }; };
15 | OBJ_38 /* NSArray+FBLFunctionalTests.m in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* NSArray+FBLFunctionalTests.m */; };
16 | OBJ_39 /* NSDictionary+FBLFunctionalTests.m in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* NSDictionary+FBLFunctionalTests.m */; };
17 | OBJ_40 /* NSOrderedSet+FBLFunctionalTests.m in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* NSOrderedSet+FBLFunctionalTests.m */; };
18 | OBJ_41 /* NSSet+FBLFunctionalTests.m in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_23 /* NSSet+FBLFunctionalTests.m */; };
19 | OBJ_43 /* FBLFunctional.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "FBLFunctional::FBLFunctional::Product" /* FBLFunctional.framework */; };
20 | OBJ_50 /* NSDictionary+FBLFunctional.m in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* NSDictionary+FBLFunctional.m */; };
21 | OBJ_51 /* NSObject+FBLFunctional.m in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* NSObject+FBLFunctional.m */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXContainerItemProxy section */
25 | 032B8162204628AD0097BF12 /* PBXContainerItemProxy */ = {
26 | isa = PBXContainerItemProxy;
27 | containerPortal = OBJ_1 /* Project object */;
28 | proxyType = 1;
29 | remoteGlobalIDString = "FBLFunctional::FBLFunctional";
30 | remoteInfo = FBLFunctional;
31 | };
32 | /* End PBXContainerItemProxy section */
33 |
34 | /* Begin PBXFileReference section */
35 | 032B816A2046298C0097BF12 /* framework.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = framework.modulemap; sourceTree = ""; };
36 | "FBLFunctional::FBLFunctional::Product" /* FBLFunctional.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = FBLFunctional.framework; sourceTree = BUILT_PRODUCTS_DIR; };
37 | "FBLFunctional::FBLFunctionalTests::Product" /* FBLFunctionalTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = FBLFunctionalTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
38 | OBJ_10 /* NSObject+FBLFunctional.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSObject+FBLFunctional.m"; sourceTree = ""; };
39 | OBJ_12 /* NSDictionary+FBLFunctional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+FBLFunctional.h"; sourceTree = ""; };
40 | OBJ_13 /* NSOrderedSet+FBLFunctional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSOrderedSet+FBLFunctional.h"; sourceTree = ""; };
41 | OBJ_14 /* NSArray+FBLFunctional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSArray+FBLFunctional.h"; sourceTree = ""; };
42 | OBJ_15 /* FBLFunctional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBLFunctional.h; sourceTree = ""; };
43 | OBJ_16 /* NSSet+FBLFunctional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSSet+FBLFunctional.h"; sourceTree = ""; };
44 | OBJ_20 /* NSArray+FBLFunctionalTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSArray+FBLFunctionalTests.m"; sourceTree = ""; };
45 | OBJ_21 /* NSDictionary+FBLFunctionalTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+FBLFunctionalTests.m"; sourceTree = ""; };
46 | OBJ_22 /* NSOrderedSet+FBLFunctionalTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSOrderedSet+FBLFunctionalTests.m"; sourceTree = ""; };
47 | OBJ_23 /* NSSet+FBLFunctionalTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSSet+FBLFunctionalTests.m"; sourceTree = ""; };
48 | OBJ_9 /* NSDictionary+FBLFunctional.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+FBLFunctional.m"; sourceTree = ""; };
49 | /* End PBXFileReference section */
50 |
51 | /* Begin PBXFrameworksBuildPhase section */
52 | OBJ_42 /* Frameworks */ = {
53 | isa = PBXFrameworksBuildPhase;
54 | buildActionMask = 0;
55 | files = (
56 | OBJ_43 /* FBLFunctional.framework in Frameworks */,
57 | );
58 | runOnlyForDeploymentPostprocessing = 0;
59 | };
60 | OBJ_52 /* Frameworks */ = {
61 | isa = PBXFrameworksBuildPhase;
62 | buildActionMask = 0;
63 | files = (
64 | );
65 | runOnlyForDeploymentPostprocessing = 0;
66 | };
67 | /* End PBXFrameworksBuildPhase section */
68 |
69 | /* Begin PBXGroup section */
70 | OBJ_11 /* include */ = {
71 | isa = PBXGroup;
72 | children = (
73 | OBJ_15 /* FBLFunctional.h */,
74 | OBJ_14 /* NSArray+FBLFunctional.h */,
75 | OBJ_12 /* NSDictionary+FBLFunctional.h */,
76 | OBJ_13 /* NSOrderedSet+FBLFunctional.h */,
77 | OBJ_16 /* NSSet+FBLFunctional.h */,
78 | 032B816A2046298C0097BF12 /* framework.modulemap */,
79 | );
80 | path = include;
81 | sourceTree = "";
82 | };
83 | OBJ_18 /* Tests */ = {
84 | isa = PBXGroup;
85 | children = (
86 | OBJ_19 /* FBLFunctionalTests */,
87 | );
88 | name = Tests;
89 | sourceTree = SOURCE_ROOT;
90 | };
91 | OBJ_19 /* FBLFunctionalTests */ = {
92 | isa = PBXGroup;
93 | children = (
94 | OBJ_20 /* NSArray+FBLFunctionalTests.m */,
95 | OBJ_21 /* NSDictionary+FBLFunctionalTests.m */,
96 | OBJ_22 /* NSOrderedSet+FBLFunctionalTests.m */,
97 | OBJ_23 /* NSSet+FBLFunctionalTests.m */,
98 | );
99 | name = FBLFunctionalTests;
100 | path = Tests/FBLFunctionalTests;
101 | sourceTree = SOURCE_ROOT;
102 | };
103 | OBJ_24 /* Products */ = {
104 | isa = PBXGroup;
105 | children = (
106 | "FBLFunctional::FBLFunctionalTests::Product" /* FBLFunctionalTests.xctest */,
107 | "FBLFunctional::FBLFunctional::Product" /* FBLFunctional.framework */,
108 | );
109 | name = Products;
110 | sourceTree = BUILT_PRODUCTS_DIR;
111 | };
112 | OBJ_5 = {
113 | isa = PBXGroup;
114 | children = (
115 | OBJ_7 /* Sources */,
116 | OBJ_18 /* Tests */,
117 | OBJ_24 /* Products */,
118 | );
119 | sourceTree = "";
120 | };
121 | OBJ_7 /* Sources */ = {
122 | isa = PBXGroup;
123 | children = (
124 | OBJ_8 /* FBLFunctional */,
125 | );
126 | name = Sources;
127 | sourceTree = SOURCE_ROOT;
128 | };
129 | OBJ_8 /* FBLFunctional */ = {
130 | isa = PBXGroup;
131 | children = (
132 | OBJ_9 /* NSDictionary+FBLFunctional.m */,
133 | OBJ_10 /* NSObject+FBLFunctional.m */,
134 | OBJ_11 /* include */,
135 | );
136 | name = FBLFunctional;
137 | path = Sources/FBLFunctional;
138 | sourceTree = SOURCE_ROOT;
139 | };
140 | /* End PBXGroup section */
141 |
142 | /* Begin PBXHeadersBuildPhase section */
143 | 032B81642046295E0097BF12 /* Headers */ = {
144 | isa = PBXHeadersBuildPhase;
145 | buildActionMask = 2147483647;
146 | files = (
147 | 032B8168204629650097BF12 /* FBLFunctional.h in Headers */,
148 | 032B8166204629650097BF12 /* NSOrderedSet+FBLFunctional.h in Headers */,
149 | 032B8165204629650097BF12 /* NSDictionary+FBLFunctional.h in Headers */,
150 | 032B8167204629650097BF12 /* NSArray+FBLFunctional.h in Headers */,
151 | 032B8169204629650097BF12 /* NSSet+FBLFunctional.h in Headers */,
152 | );
153 | runOnlyForDeploymentPostprocessing = 0;
154 | };
155 | /* End PBXHeadersBuildPhase section */
156 |
157 | /* Begin PBXNativeTarget section */
158 | "FBLFunctional::FBLFunctional" /* FBLFunctional */ = {
159 | isa = PBXNativeTarget;
160 | buildConfigurationList = OBJ_46 /* Build configuration list for PBXNativeTarget "FBLFunctional" */;
161 | buildPhases = (
162 | OBJ_49 /* Sources */,
163 | OBJ_52 /* Frameworks */,
164 | 032B81642046295E0097BF12 /* Headers */,
165 | );
166 | buildRules = (
167 | );
168 | dependencies = (
169 | );
170 | name = FBLFunctional;
171 | productName = FBLFunctional;
172 | productReference = "FBLFunctional::FBLFunctional::Product" /* FBLFunctional.framework */;
173 | productType = "com.apple.product-type.framework";
174 | };
175 | "FBLFunctional::FBLFunctionalTests" /* FBLFunctionalTests */ = {
176 | isa = PBXNativeTarget;
177 | buildConfigurationList = OBJ_34 /* Build configuration list for PBXNativeTarget "FBLFunctionalTests" */;
178 | buildPhases = (
179 | OBJ_37 /* Sources */,
180 | OBJ_42 /* Frameworks */,
181 | );
182 | buildRules = (
183 | );
184 | dependencies = (
185 | OBJ_44 /* PBXTargetDependency */,
186 | );
187 | name = FBLFunctionalTests;
188 | productName = FBLFunctionalTests;
189 | productReference = "FBLFunctional::FBLFunctionalTests::Product" /* FBLFunctionalTests.xctest */;
190 | productType = "com.apple.product-type.bundle.unit-test";
191 | };
192 | /* End PBXNativeTarget section */
193 |
194 | /* Begin PBXProject section */
195 | OBJ_1 /* Project object */ = {
196 | isa = PBXProject;
197 | attributes = {
198 | LastUpgradeCheck = 9999;
199 | };
200 | buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "FBLFunctional" */;
201 | compatibilityVersion = "Xcode 3.2";
202 | developmentRegion = English;
203 | hasScannedForEncodings = 0;
204 | knownRegions = (
205 | en,
206 | );
207 | mainGroup = OBJ_5;
208 | productRefGroup = OBJ_24 /* Products */;
209 | projectDirPath = "";
210 | projectRoot = "";
211 | targets = (
212 | "FBLFunctional::FBLFunctionalTests" /* FBLFunctionalTests */,
213 | "FBLFunctional::FBLFunctional" /* FBLFunctional */,
214 | );
215 | };
216 | /* End PBXProject section */
217 |
218 | /* Begin PBXSourcesBuildPhase section */
219 | OBJ_37 /* Sources */ = {
220 | isa = PBXSourcesBuildPhase;
221 | buildActionMask = 0;
222 | files = (
223 | OBJ_38 /* NSArray+FBLFunctionalTests.m in Sources */,
224 | OBJ_39 /* NSDictionary+FBLFunctionalTests.m in Sources */,
225 | OBJ_40 /* NSOrderedSet+FBLFunctionalTests.m in Sources */,
226 | OBJ_41 /* NSSet+FBLFunctionalTests.m in Sources */,
227 | );
228 | runOnlyForDeploymentPostprocessing = 0;
229 | };
230 | OBJ_49 /* Sources */ = {
231 | isa = PBXSourcesBuildPhase;
232 | buildActionMask = 0;
233 | files = (
234 | OBJ_50 /* NSDictionary+FBLFunctional.m in Sources */,
235 | OBJ_51 /* NSObject+FBLFunctional.m in Sources */,
236 | );
237 | runOnlyForDeploymentPostprocessing = 0;
238 | };
239 | /* End PBXSourcesBuildPhase section */
240 |
241 | /* Begin PBXTargetDependency section */
242 | OBJ_44 /* PBXTargetDependency */ = {
243 | isa = PBXTargetDependency;
244 | target = "FBLFunctional::FBLFunctional" /* FBLFunctional */;
245 | targetProxy = 032B8162204628AD0097BF12 /* PBXContainerItemProxy */;
246 | };
247 | /* End PBXTargetDependency section */
248 |
249 | /* Begin XCBuildConfiguration section */
250 | OBJ_3 /* Debug */ = {
251 | isa = XCBuildConfiguration;
252 | buildSettings = {
253 | CLANG_ENABLE_OBJC_ARC = YES;
254 | COMBINE_HIDPI_IMAGES = YES;
255 | COPY_PHASE_STRIP = NO;
256 | DEBUG_INFORMATION_FORMAT = dwarf;
257 | DYLIB_INSTALL_NAME_BASE = "@rpath";
258 | ENABLE_NS_ASSERTIONS = YES;
259 | GCC_OPTIMIZATION_LEVEL = 0;
260 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
261 | MACOSX_DEPLOYMENT_TARGET = 10.10;
262 | ONLY_ACTIVE_ARCH = YES;
263 | PRODUCT_NAME = "$(TARGET_NAME)";
264 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
265 | TVOS_DEPLOYMENT_TARGET = 9.0;
266 | USE_HEADERMAP = NO;
267 | WATCHOS_DEPLOYMENT_TARGET = 2.0;
268 | };
269 | name = Debug;
270 | };
271 | OBJ_35 /* Debug */ = {
272 | isa = XCBuildConfiguration;
273 | buildSettings = {
274 | FRAMEWORK_SEARCH_PATHS = (
275 | "$(inherited)",
276 | "$(PLATFORM_DIR)/Developer/Library/Frameworks",
277 | );
278 | HEADER_SEARCH_PATHS = (
279 | "$(inherited)",
280 | "$(SRCROOT)/Tests/FBLFunctionalTests/include",
281 | "$(SRCROOT)/Sources/FBLFunctional/include",
282 | );
283 | INFOPLIST_FILE = FBLFunctional.xcodeproj/FBLFunctionalTests_Info.plist;
284 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks";
285 | OTHER_LDFLAGS = "$(inherited)";
286 | TARGET_NAME = FBLFunctionalTests;
287 | };
288 | name = Debug;
289 | };
290 | OBJ_36 /* Release */ = {
291 | isa = XCBuildConfiguration;
292 | buildSettings = {
293 | FRAMEWORK_SEARCH_PATHS = (
294 | "$(inherited)",
295 | "$(PLATFORM_DIR)/Developer/Library/Frameworks",
296 | );
297 | HEADER_SEARCH_PATHS = (
298 | "$(inherited)",
299 | "$(SRCROOT)/Tests/FBLFunctionalTests/include",
300 | "$(SRCROOT)/Sources/FBLFunctional/include",
301 | );
302 | INFOPLIST_FILE = FBLFunctional.xcodeproj/FBLFunctionalTests_Info.plist;
303 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks";
304 | OTHER_LDFLAGS = "$(inherited)";
305 | TARGET_NAME = FBLFunctionalTests;
306 | };
307 | name = Release;
308 | };
309 | OBJ_4 /* Release */ = {
310 | isa = XCBuildConfiguration;
311 | buildSettings = {
312 | CLANG_ENABLE_OBJC_ARC = YES;
313 | COMBINE_HIDPI_IMAGES = YES;
314 | COPY_PHASE_STRIP = YES;
315 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
316 | DYLIB_INSTALL_NAME_BASE = "@rpath";
317 | GCC_OPTIMIZATION_LEVEL = s;
318 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
319 | MACOSX_DEPLOYMENT_TARGET = 10.10;
320 | PRODUCT_NAME = "$(TARGET_NAME)";
321 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator";
322 | TVOS_DEPLOYMENT_TARGET = 9.0;
323 | USE_HEADERMAP = NO;
324 | WATCHOS_DEPLOYMENT_TARGET = 2.0;
325 | };
326 | name = Release;
327 | };
328 | OBJ_47 /* Debug */ = {
329 | isa = XCBuildConfiguration;
330 | buildSettings = {
331 | DEFINES_MODULE = YES;
332 | ENABLE_TESTABILITY = YES;
333 | FRAMEWORK_SEARCH_PATHS = (
334 | "$(inherited)",
335 | "$(PLATFORM_DIR)/Developer/Library/Frameworks",
336 | );
337 | HEADER_SEARCH_PATHS = (
338 | "$(inherited)",
339 | "$(SRCROOT)/Sources/FBLFunctional/include",
340 | );
341 | INFOPLIST_FILE = FBLFunctional.xcodeproj/FBLFunctional_Info.plist;
342 | MODULEMAP_FILE = "$(SRCROOT)/Sources/FBLFunctional/include/framework.modulemap";
343 | OTHER_LDFLAGS = "$(inherited)";
344 | PRODUCT_BUNDLE_IDENTIFIER = FBLFunctional;
345 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
346 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
347 | SKIP_INSTALL = YES;
348 | TARGET_NAME = FBLFunctional;
349 | };
350 | name = Debug;
351 | };
352 | OBJ_48 /* Release */ = {
353 | isa = XCBuildConfiguration;
354 | buildSettings = {
355 | DEFINES_MODULE = YES;
356 | ENABLE_TESTABILITY = YES;
357 | FRAMEWORK_SEARCH_PATHS = (
358 | "$(inherited)",
359 | "$(PLATFORM_DIR)/Developer/Library/Frameworks",
360 | );
361 | HEADER_SEARCH_PATHS = (
362 | "$(inherited)",
363 | "$(SRCROOT)/Sources/FBLFunctional/include",
364 | );
365 | INFOPLIST_FILE = FBLFunctional.xcodeproj/FBLFunctional_Info.plist;
366 | MODULEMAP_FILE = "$(SRCROOT)/Sources/FBLFunctional/include/framework.modulemap";
367 | OTHER_LDFLAGS = "$(inherited)";
368 | PRODUCT_BUNDLE_IDENTIFIER = FBLFunctional;
369 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
370 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
371 | SKIP_INSTALL = YES;
372 | TARGET_NAME = FBLFunctional;
373 | };
374 | name = Release;
375 | };
376 | /* End XCBuildConfiguration section */
377 |
378 | /* Begin XCConfigurationList section */
379 | OBJ_2 /* Build configuration list for PBXProject "FBLFunctional" */ = {
380 | isa = XCConfigurationList;
381 | buildConfigurations = (
382 | OBJ_3 /* Debug */,
383 | OBJ_4 /* Release */,
384 | );
385 | defaultConfigurationIsVisible = 0;
386 | defaultConfigurationName = Debug;
387 | };
388 | OBJ_34 /* Build configuration list for PBXNativeTarget "FBLFunctionalTests" */ = {
389 | isa = XCConfigurationList;
390 | buildConfigurations = (
391 | OBJ_35 /* Debug */,
392 | OBJ_36 /* Release */,
393 | );
394 | defaultConfigurationIsVisible = 0;
395 | defaultConfigurationName = Debug;
396 | };
397 | OBJ_46 /* Build configuration list for PBXNativeTarget "FBLFunctional" */ = {
398 | isa = XCConfigurationList;
399 | buildConfigurations = (
400 | OBJ_47 /* Debug */,
401 | OBJ_48 /* Release */,
402 | );
403 | defaultConfigurationIsVisible = 0;
404 | defaultConfigurationName = Debug;
405 | };
406 | /* End XCConfigurationList section */
407 | };
408 | rootObject = OBJ_1 /* Project object */;
409 | }
410 |
--------------------------------------------------------------------------------
/FBLFunctional.xcodeproj/xcshareddata/xcschemes/FBLFunctional.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
34 |
40 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
66 |
67 |
73 |
74 |
75 |
76 |
77 |
78 |
84 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/FunctionalObjC.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'FunctionalObjC'
3 | s.version = '1.0.2'
4 | s.authors = 'Google Inc.'
5 | s.license = { :type => 'Apache', :file => 'LICENSE' }
6 | s.homepage = 'https://github.com/google/functional-objc'
7 | s.source = { :git => 'https://github.com/google/functional-objc.git', :tag => s.version }
8 | s.summary = 'Functional operators for Objective-C'
9 | s.description = <<-DESC
10 |
11 | An Objective-C library of functional operators, derived from Swift.Sequence,
12 | that help you write more concise and readable code for collection
13 | transformations. Foundation collections supported include: NSArray,
14 | NSDictionary, NSOrderedSet, and NSSet.
15 | DESC
16 |
17 | s.ios.deployment_target = '8.0'
18 | s.osx.deployment_target = '10.10'
19 | s.tvos.deployment_target = '9.0'
20 | s.watchos.deployment_target = '2.0'
21 |
22 | s.module_name = 'FBLFunctional'
23 | s.prefix_header_file = false
24 | s.source_files = "Sources/#{s.module_name}/**/*.{h,m}"
25 |
26 | s.test_spec "Tests" do |ts|
27 | ts.source_files = "Tests/#{s.module_name}Tests/*.{h,m}"
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:4.0
2 | // swiftlint:disable trailing_comma
3 |
4 | // To generate and open project in Xcode run:
5 | // swift package generate-xcodeproj && open FBLFunctional.xcodeproj
6 |
7 | // Copyright 2018 Google Inc. All rights reserved.
8 | //
9 | // Licensed under the Apache License, Version 2.0 (the "License");
10 | // you may not use this file except in compliance with the License.
11 | // You may obtain a copy of the License at:
12 | //
13 | // http://www.apache.org/licenses/LICENSE-2.0
14 | //
15 | // Unless required by applicable law or agreed to in writing, software
16 | // distributed under the License is distributed on an "AS IS" BASIS,
17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | // See the License for the specific language governing permissions and
19 | // limitations under the License.
20 |
21 | import PackageDescription
22 |
23 | let package = Package(
24 | name: "FBLFunctional",
25 | products: [
26 | .library(
27 | name: "FBLFunctional",
28 | targets: ["FBLFunctional"]
29 | )
30 | ],
31 | targets: [
32 | .target(
33 | name: "FBLFunctional"
34 | ),
35 | .testTarget(
36 | name: "FBLFunctionalTests",
37 | dependencies: [
38 | "FBLFunctional",
39 | ]
40 | ),
41 | ]
42 | )
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](LICENSE)
3 | [](https://travis-ci.org/google/functional-objc)
4 |
5 | # Functional operators for Objective-C
6 |
7 | An Objective-C library of functional operators, derived from `Swift.Sequence`,
8 | that help you write more concise and readable code for collection
9 | transformations. Foundation collections supported include: `NSArray`,
10 | `NSDictionary`, `NSOrderedSet`, and `NSSet`.
11 |
12 | ## Functional Operators
13 |
14 | ### Filter
15 |
16 | Loops over a collection and returns an array that contains elements that meet a
17 | condition.
18 |
19 | ```objectivec
20 | NSArray *filteredArray = [@[ @13, @42, @0 ] fbl_filter:^BOOL(NSNumber *value) {
21 | return value.integerValue > 0;
22 | }];
23 | XCTAssertEqualObjects(filteredArray, @[ @13, @42 ]);
24 | ```
25 |
26 | ### First
27 |
28 | Returns the first element in the collection that satisfies a condition.
29 |
30 | ```objectivec
31 | NSNumber *firstValue = [@[ @13, @42, @100 ] fbl_first:^BOOL(NSNumber *value) {
32 | return value.integerValue > 20;
33 | }];
34 | XCTAssertEqualObjects(firstValue, @42);
35 | ```
36 |
37 | ### FlatMap
38 |
39 | Similar to [`map`](#map), but can also flatten a collection of collections.
40 |
41 | ```objectivec
42 | NSArray *> *originalArray = @[ @[ @13, @42 ], @[ @14, @43 ], @[] ];
43 | NSArray *flatMappedArray = [originalArray fbl_flatMap:^id(NSArray *value) {
44 | return value.count > 0 ? value : nil;
45 | }];
46 | XCTAssertEqualObjects(flatMappedArray, @[ @13, @42, @14, @43 ]);
47 | ```
48 |
49 | ### ForEach
50 |
51 | Invokes a block on each element of the collection in the same order as a for-in
52 | loop.
53 |
54 | ```objectivec
55 | [@[ @13, @42, @100 ] fbl_forEach:^(NSNumber *value) {
56 | // Invokes this block for values @13, @42, @100
57 | }];
58 | ```
59 |
60 | ### Map
61 |
62 | Loops over a collection and applies the same operation to each element in the
63 | collection.
64 |
65 | ```objectivec
66 | NSArray *mappedArray = [@[ @13, @42, @0 ] fbl_map:^id(NSNumber *value) {
67 | if (value.integerValue == 0) {
68 | return nil;
69 | }
70 | return value.stringValue;
71 | }];
72 | XCTAssertEqualObjects(mappedArray, @[ @"13", @"42", [NSNull null] ]);
73 | ```
74 |
75 | ### Reduce
76 |
77 | Combines all items in a collection to create a single value.
78 |
79 | ```objectivec
80 | NSNumber *reducedValue =
81 | [@[ @13, @42, @100 ] fbl_reduce:@0
82 | combine:^NSNumber *(NSNumber *accumulator, NSNumber *value) {
83 | return @(accumulator.integerValue + value.integerValue);
84 | }];
85 | XCTAssertEqualObjects(reducedValue, @(13 + 42 + 100));
86 | ```
87 |
88 | ### Zip
89 |
90 | Creates an array of pairs built from the two input collections.
91 |
92 | ```objectivec
93 | NSArray *zippedArray = [@[ @13, @42, @101 ] fbl_zip:@[ @"100", @"14" ]];
94 | XCTAssertEqualObjects(zippedArray, @[ @[ @13, @"100" ], @[ @42, @"14" ] ]);
95 | ```
96 |
97 | ## Setup
98 |
99 | ### CocoaPods
100 |
101 | Add the following to your `Podfile`:
102 |
103 | ```ruby
104 | pod 'FunctionalObjC', '~> 1.0'
105 | ```
106 |
107 | Or, if you would also like to include the tests:
108 |
109 | ```ruby
110 | pod 'FunctionalObjC', '~> 1.0', :testspecs => ['Tests']
111 | ```
112 |
113 | Then, run `pod install`.
114 |
115 | ### Carthage
116 |
117 | Add the following to your `Cartfile`:
118 |
119 | ```
120 | github "google/functional-objc"
121 | ```
122 |
123 | Then, run `carthage update` and follow the [rest of instructions](https://github.com/Carthage/Carthage#getting-started).
124 |
125 | ### Import
126 |
127 | Import the umbrella header as:
128 |
129 | ```objectivec
130 | #import
131 | ```
132 |
133 | Or:
134 |
135 | ```objectivec
136 | #import "FBLFunctional.h"
137 | ```
138 |
139 | Or, the module:
140 |
141 | ```objectivec
142 | @import FBLFunctional;
143 | ```
144 |
--------------------------------------------------------------------------------
/Sources/FBLFunctional/NSDictionary+FBLFunctional.m:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "NSDictionary+FBLFunctional.h"
18 |
19 | FOUNDATION_EXTERN NSArray *FBLZip(id container1, id container2);
20 |
21 | static NSDictionary *FBLDictionaryFilter(NSDictionary *dictionary, BOOL (^predicate)(id, id)) {
22 | NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
23 | for (id key in dictionary) {
24 | id value = dictionary[key];
25 | if (predicate(key, value)) {
26 | result[key] = value;
27 | }
28 | }
29 | return result;
30 | }
31 |
32 | static id __nullable FBLDictionaryFirst(NSDictionary *dictionary, BOOL (^predicate)(id, id)) {
33 | for (id key in dictionary) {
34 | if (predicate(key, dictionary[key])) {
35 | return key;
36 | }
37 | }
38 | return nil;
39 | }
40 |
41 | static NSArray *FBLDictionaryFlatMap(NSDictionary *dictionary, id __nullable (^mapper)(id, id)) {
42 | NSMutableArray *result = [[NSMutableArray alloc] init];
43 | for (id key in dictionary) {
44 | id mapped = mapper(key, dictionary[key]);
45 | if ([mapped isKindOfClass:[NSDictionary class]]) {
46 | [result addObjectsFromArray:[mapped allValues]];
47 | } else if (mapped) {
48 | [result addObject:mapped];
49 | }
50 | }
51 | return result;
52 | }
53 |
54 | static void FBLDictionaryForEach(NSDictionary *dictionary, void (^block)(id, id)) {
55 | for (id key in dictionary) {
56 | block(key, dictionary[key]);
57 | }
58 | }
59 |
60 | static NSArray *FBLDictionaryMap(NSDictionary *dictionary, id __nullable (^mapper)(id, id)) {
61 | NSMutableArray *result = [[NSMutableArray alloc] init];
62 | for (id key in dictionary) {
63 | id mapped = mapper(key, dictionary[key]);
64 | [result addObject:mapped ?: [NSNull null]];
65 | }
66 | return result;
67 | }
68 |
69 | static NSDictionary *FBLDictionaryMapValues(NSDictionary *dictionary, id __nullable (^mapper)(id)) {
70 | NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
71 | for (id key in dictionary) {
72 | id mapped = mapper(dictionary[key]);
73 | result[key] = mapped ?: [NSNull null];
74 | }
75 | return result;
76 | }
77 |
78 | static id __nullable FBLDictionaryReduce(NSDictionary *dictionary, id __nullable initialValue,
79 | id __nullable (^reducer)(id __nullable, id, id)) {
80 | id result = initialValue;
81 | for (id key in dictionary) {
82 | result = reducer(result, key, dictionary[key]);
83 | }
84 | return result;
85 | }
86 |
87 | @implementation NSDictionary (FBLFunctionalAdditions)
88 |
89 | - (instancetype)fbl_filter:(NS_NOESCAPE BOOL (^)(id, id))predicate {
90 | NSParameterAssert(predicate);
91 |
92 | return FBLDictionaryFilter(self, predicate);
93 | }
94 |
95 | - (nullable id)fbl_first:(NS_NOESCAPE BOOL (^)(id, id))predicate {
96 | NSParameterAssert(predicate);
97 |
98 | return FBLDictionaryFirst(self, predicate);
99 | }
100 |
101 | - (NSArray *)fbl_flatMap:(NS_NOESCAPE id (^)(id, id))mapper {
102 | NSParameterAssert(mapper);
103 |
104 | return FBLDictionaryFlatMap(self, mapper);
105 | }
106 |
107 | - (void)fbl_forEach:(NS_NOESCAPE void (^)(id, id))block {
108 | NSParameterAssert(block);
109 |
110 | FBLDictionaryForEach(self, block);
111 | }
112 |
113 | - (NSArray *)fbl_map:(NS_NOESCAPE id (^)(id, id))mapper {
114 | NSParameterAssert(mapper);
115 |
116 | return FBLDictionaryMap(self, mapper);
117 | }
118 |
119 | - (NSDictionary *)fbl_mapValues:(NS_NOESCAPE id (^)(id))mapper {
120 | NSParameterAssert(mapper);
121 |
122 | return FBLDictionaryMapValues(self, mapper);
123 | }
124 |
125 | - (nullable id)fbl_reduce:(nullable NS_NOESCAPE id)initialValue
126 | combine:(NS_NOESCAPE id (^)(id, id, id))reducer {
127 | NSParameterAssert(reducer);
128 |
129 | return FBLDictionaryReduce(self, initialValue, reducer);
130 | }
131 |
132 | - (NSArray *)fbl_zip:(id)container {
133 | NSParameterAssert([self isKindOfClass:[NSDictionary class]]);
134 | NSParameterAssert(
135 | [container isKindOfClass:[NSDictionary class]] || [container isKindOfClass:[NSArray class]] ||
136 | [container isKindOfClass:[NSSet class]] || [container isKindOfClass:[NSOrderedSet class]]);
137 |
138 | return FBLZip(self, container);
139 | }
140 |
141 | @end
142 |
--------------------------------------------------------------------------------
/Sources/FBLFunctional/NSObject+FBLFunctional.m:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "NSArray+FBLFunctional.h"
18 | #import "NSOrderedSet+FBLFunctional.h"
19 | #import "NSSet+FBLFunctional.h"
20 |
21 | NSArray *FBLZip(id container1, id container2) {
22 | NSMutableArray *result = [[NSMutableArray alloc] init];
23 | NSEnumerator *enumerator1 = [container1 objectEnumerator];
24 | NSEnumerator *enumerator2 = [container2 objectEnumerator];
25 | for (;;) {
26 | id object1 = [enumerator1 nextObject];
27 | id object2 = [enumerator2 nextObject];
28 | if (!object1 || !object2) break;
29 | [result addObject:@[ object1, object2 ]];
30 | }
31 | return result;
32 | }
33 |
34 | static NSArray *FBLArrayFromContainer(id container) {
35 | NSArray *result = @[];
36 | if ([container isKindOfClass:[NSArray class]]) {
37 | result = container;
38 | } else if ([container isKindOfClass:[NSSet class]]) {
39 | result = [container allObjects];
40 | } else if ([container isKindOfClass:[NSOrderedSet class]]) {
41 | result = [container array];
42 | }
43 | return result;
44 | }
45 |
46 | /**
47 | Compares object classes similarly to isKindOfClass, which doesn't work for class clusters:
48 | NSArray isn't kind of class NSArray when two instances are compared.
49 | This method compares each instance to generic container class instead.
50 | */
51 | static BOOL FBLSameKindContainers(id container1, id container2) {
52 | // Both containers are NSArrays.
53 | if ([container1 isKindOfClass:[NSArray class]] && [container2 isKindOfClass:[NSArray class]]) {
54 | return YES;
55 | }
56 | // Both containers are NSOrderedSets.
57 | if ([container1 isKindOfClass:[NSOrderedSet class]] &&
58 | [container2 isKindOfClass:[NSOrderedSet class]]) {
59 | return YES;
60 | }
61 | // Both containers are NSSets.
62 | if ([container1 isKindOfClass:[NSSet class]] && [container2 isKindOfClass:[NSSet class]]) {
63 | return YES;
64 | }
65 | return NO;
66 | }
67 |
68 | static id FBLFilter(id container, BOOL (^predicate)(id)) {
69 | id result = [[[container class] new] mutableCopy];
70 | for (id object in container) {
71 | if (predicate(object)) {
72 | [result addObject:object];
73 | }
74 | }
75 | return result;
76 | }
77 |
78 | static id __nullable FBLFirst(id container, BOOL (^predicate)(id)) {
79 | for (id object in container) {
80 | if (predicate(object)) {
81 | return object;
82 | }
83 | }
84 | return nil;
85 | }
86 |
87 | static NSArray *FBLFlatMap(id container, id __nullable (^mapper)(id)) {
88 | NSMutableArray *result = [[NSMutableArray alloc] init];
89 | for (id object in container) {
90 | id mapped = mapper(object);
91 | if (FBLSameKindContainers(container, mapped)) {
92 | [result addObjectsFromArray:FBLArrayFromContainer(mapped)];
93 | } else if (mapped) {
94 | [result addObject:mapped];
95 | }
96 | }
97 | return result;
98 | }
99 |
100 | static void FBLForEach(id container, void (^block)(id)) {
101 | for (id object in container) {
102 | block(object);
103 | }
104 | }
105 |
106 | static NSArray *FBLMap(id container, id __nullable (^mapper)(id)) {
107 | NSMutableArray *result = [[NSMutableArray alloc] init];
108 | for (id object in container) {
109 | id mapped = mapper(object);
110 | [result addObject:mapped ?: [NSNull null]];
111 | }
112 | return result;
113 | }
114 |
115 | static id __nullable FBLReduce(id container, id __nullable initialValue,
116 | id __nullable (^reducer)(id __nullable, id)) {
117 | id result = initialValue;
118 | for (id object in container) {
119 | result = reducer(result, object);
120 | }
121 | return result;
122 | }
123 |
124 | /// Common implementation for NSArray, NSSet and NSOrderedSet to avoid boilerplate code.
125 | @implementation NSObject (FBLFunctionalAdditions)
126 |
127 | - (instancetype)fbl_filter:(BOOL (^)(id))predicate {
128 | NSParameterAssert([self isKindOfClass:[NSArray class]] || [self isKindOfClass:[NSSet class]] ||
129 | [self isKindOfClass:[NSOrderedSet class]]);
130 | NSParameterAssert(predicate);
131 |
132 | return FBLFilter((id)self, predicate);
133 | }
134 |
135 | - (nullable id)fbl_first:(BOOL (^)(id))predicate {
136 | NSParameterAssert([self isKindOfClass:[NSArray class]] || [self isKindOfClass:[NSSet class]] ||
137 | [self isKindOfClass:[NSOrderedSet class]]);
138 | NSParameterAssert(predicate);
139 |
140 | return FBLFirst((id)self, predicate);
141 | }
142 |
143 | - (NSArray *)fbl_flatMap:(id (^)(id))mapper {
144 | NSParameterAssert([self isKindOfClass:[NSArray class]] || [self isKindOfClass:[NSSet class]] ||
145 | [self isKindOfClass:[NSOrderedSet class]]);
146 | NSParameterAssert(mapper);
147 |
148 | return FBLFlatMap((id)self, mapper);
149 | }
150 |
151 | - (void)fbl_forEach:(void (^)(id))block {
152 | NSParameterAssert([self isKindOfClass:[NSArray class]] || [self isKindOfClass:[NSSet class]] ||
153 | [self isKindOfClass:[NSOrderedSet class]]);
154 | NSParameterAssert(block);
155 |
156 | FBLForEach((id)self, block);
157 | }
158 |
159 | - (NSArray *)fbl_map:(id (^)(id))mapper {
160 | NSParameterAssert([self isKindOfClass:[NSArray class]] || [self isKindOfClass:[NSSet class]] ||
161 | [self isKindOfClass:[NSOrderedSet class]]);
162 | NSParameterAssert(mapper);
163 |
164 | return FBLMap((id)self, mapper);
165 | }
166 |
167 | - (nullable id)fbl_reduce:(nullable id)initialValue combine:(id (^)(id, id))reducer {
168 | NSParameterAssert([self isKindOfClass:[NSArray class]] || [self isKindOfClass:[NSSet class]] ||
169 | [self isKindOfClass:[NSOrderedSet class]]);
170 | NSParameterAssert(reducer);
171 |
172 | return FBLReduce((id)self, initialValue, reducer);
173 | }
174 |
175 | - (NSArray *)fbl_zip:(id)container {
176 | NSParameterAssert([self isKindOfClass:[NSArray class]] || [self isKindOfClass:[NSSet class]] ||
177 | [self isKindOfClass:[NSOrderedSet class]]);
178 | NSParameterAssert([container isKindOfClass:[NSArray class]] ||
179 | [container isKindOfClass:[NSSet class]] ||
180 | [container isKindOfClass:[NSOrderedSet class]]);
181 |
182 | return FBLZip(self, container);
183 | }
184 |
185 | @end
186 |
--------------------------------------------------------------------------------
/Sources/FBLFunctional/include/FBLFunctional.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "NSArray+FBLFunctional.h"
18 | #import "NSDictionary+FBLFunctional.h"
19 | #import "NSOrderedSet+FBLFunctional.h"
20 | #import "NSSet+FBLFunctional.h"
21 |
--------------------------------------------------------------------------------
/Sources/FBLFunctional/include/NSArray+FBLFunctional.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | NS_ASSUME_NONNULL_BEGIN
20 |
21 | @interface NSArray(FBLFunctionalAdditions)
22 |
23 | typedef void (^FBLFunctionalArrayEnumeratorBlock)(ObjectType value);
24 | typedef id __nullable (^FBLFunctionalArrayMapperBlock)(ObjectType value);
25 | typedef BOOL (^FBLFunctionalArrayPredicateBlock)(ObjectType value);
26 | typedef id __nullable (^FBLFunctionalArrayReducerBlock)(id __nullable accumulator,
27 | ObjectType value);
28 |
29 | /**
30 | Returns an array containing receiver's elements that satisfy the given predicate.
31 | */
32 | - (instancetype)fbl_filter:(NS_NOESCAPE FBLFunctionalArrayPredicateBlock)predicate
33 | NS_SWIFT_UNAVAILABLE("");
34 |
35 | /**
36 | Returns the first element of the receiver that satisfies the given predicate.
37 | */
38 | - (nullable ObjectType)fbl_first:(NS_NOESCAPE FBLFunctionalArrayPredicateBlock)predicate
39 | NS_SWIFT_UNAVAILABLE("");
40 |
41 | /**
42 | Returns an array containing the results of mapping the given mapper over receiver’s elements.
43 | Mapped nil is ignored. Mapped NSArray is flattened: its elements are appended to the results.
44 | */
45 | - (NSArray *)fbl_flatMap:(NS_NOESCAPE FBLFunctionalArrayMapperBlock)mapper NS_SWIFT_UNAVAILABLE("");
46 |
47 | /**
48 | Calls the given block on each element of the receiver in the same order as a for-in loop.
49 | */
50 | - (void)fbl_forEach:(NS_NOESCAPE FBLFunctionalArrayEnumeratorBlock)block NS_SWIFT_UNAVAILABLE("");
51 |
52 | /**
53 | Returns an array containing the results of mapping the given mapper over receiver’s elements.
54 | Mapped nil appears as NSNull in resulting array.
55 | */
56 | - (NSArray *)fbl_map:(NS_NOESCAPE FBLFunctionalArrayMapperBlock)mapper NS_SWIFT_UNAVAILABLE("");
57 |
58 | /**
59 | Returns the result of combining receiver's elements using the given reducer.
60 | */
61 | - (nullable id)fbl_reduce:(nullable id)initialValue
62 | combine:(NS_NOESCAPE FBLFunctionalArrayReducerBlock)reducer
63 | NS_SWIFT_UNAVAILABLE("");
64 |
65 | /**
66 | Returns an array of pairs built out of the receiver's and provided elements. If the two containers
67 | have different counts, the resulting array is the same count as the shorter container.
68 | */
69 | - (NSArray *)fbl_zip:(id)container NS_SWIFT_UNAVAILABLE("");
70 |
71 | @end
72 |
73 | NS_ASSUME_NONNULL_END
74 |
--------------------------------------------------------------------------------
/Sources/FBLFunctional/include/NSDictionary+FBLFunctional.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | NS_ASSUME_NONNULL_BEGIN
20 |
21 | @interface NSDictionary(FBLFunctionalAdditions)
22 |
23 | typedef void (^FBLFunctionalDictionaryEnumeratorBlock)(KeyType key, ObjectType value);
24 | typedef id __nullable (^FBLFunctionalDictionaryMapperBlock)(KeyType key, ObjectType value);
25 | typedef BOOL (^FBLFunctionalDictionaryPredicateBlock)(KeyType key, ObjectType value);
26 | typedef id __nullable (^FBLFunctionalDictionaryReducerBlock)(id __nullable accumulator, KeyType key,
27 | ObjectType value);
28 | typedef id __nullable (^FBLFunctionalDictionaryValueMapperBlock)(ObjectType value);
29 |
30 | /**
31 | Returns a dictionary containing receiver's elements that satisfy the given predicate.
32 | */
33 | - (instancetype)fbl_filter:(NS_NOESCAPE FBLFunctionalDictionaryPredicateBlock)predicate
34 | NS_SWIFT_UNAVAILABLE("");
35 |
36 | /**
37 | Returns the key of the first element of the receiver that satisfies the given predicate.
38 | */
39 | - (nullable KeyType)fbl_first:(NS_NOESCAPE FBLFunctionalDictionaryPredicateBlock)predicate
40 | NS_SWIFT_UNAVAILABLE("");
41 |
42 | /**
43 | Returns an array containing the results of mapping the given mapper over receiver’s elements.
44 | Mapped nil is ignored. Mapped NSDictionary is flattened: its values are appended to the results.
45 | */
46 | - (NSArray *)fbl_flatMap:(NS_NOESCAPE FBLFunctionalDictionaryMapperBlock)mapper
47 | NS_SWIFT_UNAVAILABLE("");
48 |
49 | /**
50 | Calls the given block on each element of the receiver in the same order as a for-in loop.
51 | */
52 | - (void)fbl_forEach:(NS_NOESCAPE FBLFunctionalDictionaryEnumeratorBlock)block
53 | NS_SWIFT_UNAVAILABLE("");
54 |
55 | /**
56 | Returns an array containing the results of mapping the given mapper over receiver’s elements.
57 | Mapped nil appears as NSNull in resulting array.
58 | */
59 | - (NSArray *)fbl_map:(NS_NOESCAPE FBLFunctionalDictionaryMapperBlock)mapper
60 | NS_SWIFT_UNAVAILABLE("");
61 |
62 | /**
63 | Returns a dictionary containing receiver’s keys with the values transformed by the given mapper.
64 | Mapped nil appears as NSNull in resulting array.
65 | */
66 | - (NSDictionary *)fbl_mapValues:
67 | (NS_NOESCAPE FBLFunctionalDictionaryValueMapperBlock)mapper NS_SWIFT_UNAVAILABLE("");
68 |
69 | /**
70 | Returns the result of combining receiver's elements using the given reducer.
71 | */
72 | - (nullable id)fbl_reduce:(nullable id)initialValue
73 | combine:(NS_NOESCAPE FBLFunctionalDictionaryReducerBlock)reducer
74 | NS_SWIFT_UNAVAILABLE("");
75 |
76 | /**
77 | Returns an array of pairs built out of the receiver's and provided elements. If the two containers
78 | have different counts, the resulting array is the same count as the shorter container.
79 | */
80 | - (NSArray *)fbl_zip:(id)container NS_SWIFT_UNAVAILABLE("");
81 |
82 | @end
83 |
84 | NS_ASSUME_NONNULL_END
85 |
--------------------------------------------------------------------------------
/Sources/FBLFunctional/include/NSOrderedSet+FBLFunctional.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | NS_ASSUME_NONNULL_BEGIN
20 |
21 | @interface NSOrderedSet(FBLFunctionalAdditions)
22 |
23 | typedef void (^FBLFunctionalOrderedSetEnumeratorBlock)(ObjectType value);
24 | typedef id __nullable (^FBLFunctionalOrderedSetMapperBlock)(ObjectType value);
25 | typedef BOOL (^FBLFunctionalOrderedSetPredicateBlock)(ObjectType value);
26 | typedef id __nullable (^FBLFunctionalOrderedSetReducerBlock)(id __nullable accumulator,
27 | ObjectType value);
28 |
29 | /**
30 | Returns an ordered set containing receiver's elements that satisfy the given predicate.
31 | */
32 | - (instancetype)fbl_filter:(NS_NOESCAPE FBLFunctionalOrderedSetPredicateBlock)predicate
33 | NS_SWIFT_UNAVAILABLE("");
34 |
35 | /**
36 | Returns the first element of the receiver that satisfies the given predicate.
37 | */
38 | - (nullable ObjectType)fbl_first:(NS_NOESCAPE FBLFunctionalOrderedSetPredicateBlock)predicate
39 | NS_SWIFT_UNAVAILABLE("");
40 |
41 | /**
42 | Returns an array containing the results of mapping the given mapper over receiver’s elements.
43 | Mapped nil is ignored. Mapped NSOrderedSet is flattened: its elements are appended to the results.
44 | */
45 | - (NSArray *)fbl_flatMap:(NS_NOESCAPE FBLFunctionalOrderedSetMapperBlock)mapper
46 | NS_SWIFT_UNAVAILABLE("");
47 |
48 | /**
49 | Calls the given block on each element of the receiver in the same order as a for-in loop.
50 | */
51 | - (void)fbl_forEach:(NS_NOESCAPE FBLFunctionalOrderedSetEnumeratorBlock)block
52 | NS_SWIFT_UNAVAILABLE("");
53 |
54 | /**
55 | Returns an array containing the results of mapping the given mapper over receiver’s elements.
56 | Mapped nil appears as NSNull in resulting array.
57 | */
58 | - (NSArray *)fbl_map:(NS_NOESCAPE FBLFunctionalOrderedSetMapperBlock)mapper
59 | NS_SWIFT_UNAVAILABLE("");
60 |
61 | /**
62 | Returns the result of combining receiver's elements using the given reducer.
63 | */
64 | - (nullable id)fbl_reduce:(nullable id)initial
65 | combine:(NS_NOESCAPE FBLFunctionalOrderedSetReducerBlock)reducer
66 | NS_SWIFT_UNAVAILABLE("");
67 |
68 | /**
69 | Returns an array of pairs built out of the receiver's and provided elements. If the two containers
70 | have different counts, the resulting array is the same count as the shorter container.
71 | */
72 | - (NSArray *)fbl_zip:(id)container NS_SWIFT_UNAVAILABLE("");
73 |
74 | @end
75 |
76 | NS_ASSUME_NONNULL_END
77 |
--------------------------------------------------------------------------------
/Sources/FBLFunctional/include/NSSet+FBLFunctional.h:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import
18 |
19 | NS_ASSUME_NONNULL_BEGIN
20 |
21 | @interface NSSet(FBLFunctionalAdditions)
22 |
23 | typedef void (^FBLFunctionalSetEnumeratorBlock)(ObjectType value);
24 | typedef id __nullable (^FBLFunctionalSetMapperBlock)(ObjectType value);
25 | typedef BOOL (^FBLFunctionalSetPredicateBlock)(ObjectType value);
26 | typedef id __nullable (^FBLFunctionalSetReducerBlock)(id __nullable accumulator, ObjectType value);
27 |
28 | /**
29 | Returns a set containing receiver's elements that satisfy the given predicate.
30 | */
31 | - (instancetype)fbl_filter:(NS_NOESCAPE FBLFunctionalSetPredicateBlock)predicate
32 | NS_SWIFT_UNAVAILABLE("");
33 |
34 | /**
35 | Returns the first element of the receiver that satisfies the given predicate.
36 | */
37 | - (nullable ObjectType)fbl_first:(NS_NOESCAPE FBLFunctionalSetPredicateBlock)predicate
38 | NS_SWIFT_UNAVAILABLE("");
39 |
40 | /**
41 | Returns an array containing the results of mapping the given mapper over receiver’s elements.
42 | Mapped nil is ignored. Mapped NSSet is flattened: its elements are appended to the results.
43 | */
44 | - (NSArray *)fbl_flatMap:(NS_NOESCAPE FBLFunctionalSetMapperBlock)mapper NS_SWIFT_UNAVAILABLE("");
45 |
46 | /**
47 | Calls the given block on each element of the receiver in the same order as a for-in loop.
48 | */
49 | - (void)fbl_forEach:(NS_NOESCAPE FBLFunctionalSetEnumeratorBlock)block NS_SWIFT_UNAVAILABLE("");
50 |
51 | /**
52 | Returns an array containing the results of mapping the given mapper over receiver’s elements.
53 | Mapped nil appears as NSNull in resulting array.
54 | */
55 | - (NSArray *)fbl_map:(NS_NOESCAPE FBLFunctionalSetMapperBlock)mapper NS_SWIFT_UNAVAILABLE("");
56 |
57 | /**
58 | Returns the result of combining receiver's elements using the given reducer.
59 | */
60 | - (nullable id)fbl_reduce:(nullable id)initial
61 | combine:(NS_NOESCAPE FBLFunctionalSetReducerBlock)reducer
62 | NS_SWIFT_UNAVAILABLE("");
63 |
64 | /**
65 | Returns an array of pairs built out of the receiver's and provided elements. If the two containers
66 | have different counts, the resulting array is the same count as the shorter container.
67 | */
68 | - (NSArray *)fbl_zip:(id)container NS_SWIFT_UNAVAILABLE("");
69 |
70 | @end
71 |
72 | NS_ASSUME_NONNULL_END
73 |
--------------------------------------------------------------------------------
/Sources/FBLFunctional/include/framework.modulemap:
--------------------------------------------------------------------------------
1 | framework module FBLFunctional {
2 | umbrella header "FBLFunctional.h"
3 |
4 | header "NSArray+FBLFunctional.h"
5 | header "NSDictionary+FBLFunctional.h"
6 | header "NSOrderedSet+FBLFunctional.h"
7 | header "NSSet+FBLFunctional.h"
8 |
9 | export *
10 | }
11 |
--------------------------------------------------------------------------------
/Sources/FBLFunctional/include/module.modulemap:
--------------------------------------------------------------------------------
1 | module FBLFunctional {
2 | umbrella header "FBLFunctional.h"
3 |
4 | header "NSArray+FBLFunctional.h"
5 | header "NSDictionary+FBLFunctional.h"
6 | header "NSOrderedSet+FBLFunctional.h"
7 | header "NSSet+FBLFunctional.h"
8 |
9 | export *
10 | }
11 |
--------------------------------------------------------------------------------
/Tests/FBLFunctionalTests/NSArray+FBLFunctionalTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "NSArray+FBLFunctional.h"
18 |
19 | #import
20 |
21 | @interface NSArrayFBLFunctionalTests : XCTestCase
22 | @end
23 |
24 | @implementation NSArrayFBLFunctionalTests
25 |
26 | - (void)testFilterArray {
27 | // Arrange.
28 | NSArray *originalArray = @[ @13, @42, @0 ];
29 | NSArray *expectedArray = @[ @13, @42 ];
30 |
31 | // Act.
32 | NSArray *resultingArray = [originalArray fbl_filter:^BOOL(NSNumber *value) {
33 | return value.integerValue > 0;
34 | }];
35 |
36 | // Assert.
37 | XCTAssertEqualObjects(resultingArray, expectedArray);
38 | }
39 |
40 | - (void)testFirstArray {
41 | // Arrange.
42 | NSArray *originalArray = @[ @13, @42, @100 ];
43 | NSNumber *expectedValue = @42;
44 |
45 | // Act.
46 | NSNumber *resultingValue = [originalArray fbl_first:^BOOL(NSNumber *value) {
47 | return value.integerValue > 20;
48 | }];
49 |
50 | // Assert.
51 | XCTAssertEqualObjects(resultingValue, expectedValue);
52 | }
53 |
54 | - (void)testFlatMapArray {
55 | // Arrange.
56 | NSArray *> *originalArray = @[ @[ @13, @42 ], @[ @14, @43 ], @[] ];
57 | NSArray *expectedArray = @[ @13, @42, @14, @43 ];
58 |
59 | // Act.
60 | NSArray *resultingArray = [originalArray fbl_flatMap:^id(NSArray *value) {
61 | return value.count > 0 ? value : nil;
62 | }];
63 |
64 | // Assert.
65 | XCTAssertEqualObjects(resultingArray, expectedArray);
66 | }
67 |
68 | - (void)testForEachArray {
69 | // Arrange.
70 | NSArray *originalArray = @[ @13, @42, @100 ];
71 | NSMutableArray *resultingArray = [[NSMutableArray alloc] init];
72 |
73 | // Act.
74 | [originalArray fbl_forEach:^(NSNumber *value) {
75 | [resultingArray addObject:value];
76 | }];
77 |
78 | // Assert.
79 | XCTAssertEqualObjects(originalArray, resultingArray);
80 | }
81 |
82 | - (void)testMapArray {
83 | // Arrange.
84 | NSArray *originalArray = @[ @13, @42, @0 ];
85 | NSArray *expectedArray = @[ @"13", @"42", (NSString *)[NSNull null] ];
86 |
87 | // Act.
88 | NSArray *resultingArray = [originalArray fbl_map:^id(NSNumber *value) {
89 | if (value.integerValue == 0) {
90 | return nil;
91 | }
92 | return value.stringValue;
93 | }];
94 |
95 | // Assert.
96 | XCTAssertEqualObjects(resultingArray, expectedArray);
97 | }
98 |
99 | - (void)testReduceArray {
100 | // Arrange.
101 | NSArray *originalArray = @[ @13, @42, @100 ];
102 | NSNumber *expectedValue = @(13 + 42 + 100);
103 |
104 | // Act.
105 | NSNumber *resultingValue =
106 | [originalArray fbl_reduce:@0
107 | combine:^NSNumber *(NSNumber *accumulator, NSNumber *value) {
108 | return @(accumulator.integerValue + value.integerValue);
109 | }];
110 |
111 | // Assert.
112 | XCTAssertEqualObjects(resultingValue, expectedValue);
113 | }
114 |
115 | - (void)testZipArray {
116 | // Arrange.
117 | NSArray *array1 = @[ @13, @42, @101 ];
118 | NSArray *array2 = @[ @"100", @"14" ];
119 | NSArray *expectedArray = @[ @[ @13, @"100" ], @[ @42, @"14" ] ];
120 |
121 | // Act.
122 | NSArray *resultingArray = [array1 fbl_zip:array2];
123 |
124 | // Assert.
125 | XCTAssertEqualObjects(resultingArray, expectedArray);
126 | }
127 |
128 | - (void)testZipArrayWithDifferentContainerTypes {
129 | // Arrange.
130 | NSArray *array = @[ @13, @42, @101 ];
131 | NSSet *set = [NSSet setWithArray:@[ @13, @42 ]];
132 | NSUInteger expectedCount = MIN(array.count, set.count);
133 |
134 | // Act.
135 | NSArray *resultingArray = [array fbl_zip:set];
136 |
137 | // Assert.
138 | XCTAssertEqual(resultingArray.count, expectedCount);
139 | for (NSArray *array in resultingArray) {
140 | XCTAssertTrue([array containsObject:array.firstObject]);
141 | XCTAssertTrue([set containsObject:array.lastObject]);
142 | }
143 | }
144 |
145 | @end
146 |
--------------------------------------------------------------------------------
/Tests/FBLFunctionalTests/NSDictionary+FBLFunctionalTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "NSDictionary+FBLFunctional.h"
18 |
19 | #import
20 |
21 | @interface NSDictionaryFBLFunctionalTests : XCTestCase
22 | @end
23 |
24 | @implementation NSDictionaryFBLFunctionalTests
25 |
26 | - (void)testFilterDictionary {
27 | // Arrange.
28 | NSDictionary *originalDictionary = @{ @"1" : @12, @"2" : @40, @"0" : @0 };
29 | NSDictionary *expectedDictionary = @{ @"1" : @12, @"2" : @40 };
30 |
31 | // Act.
32 | NSDictionary *resultingDictionary =
33 | [originalDictionary fbl_filter:^BOOL(NSString __unused *_, NSNumber *value) {
34 | return value.integerValue > 0;
35 | }];
36 |
37 | // Assert.
38 | XCTAssertEqualObjects(resultingDictionary, expectedDictionary);
39 | }
40 |
41 | - (void)testFirstDictionary {
42 | // Arrange.
43 | NSDictionary *originalDictionary = @{ @"1" : @13, @"2" : @42, @"3" : @0 };
44 | NSString *expectedKey = @"2";
45 |
46 | // Act.
47 | NSString *resultingKey =
48 | [originalDictionary fbl_first:^BOOL(NSString __unused *_, NSNumber *value) {
49 | return value.integerValue > 20;
50 | }];
51 |
52 | // Assert.
53 | XCTAssertEqualObjects(resultingKey, expectedKey);
54 | }
55 |
56 | - (void)testForEachDictionary {
57 | // Arrange.
58 | NSDictionary *originalDictionary = @{ @"1" : @13, @"2" : @42, @"3" : @0 };
59 | NSMutableDictionary *expectedDictionary =
60 | [[NSMutableDictionary alloc] init];
61 |
62 | // Act.
63 | [originalDictionary fbl_forEach:^(NSString *key, NSNumber *value) {
64 | expectedDictionary[key] = value;
65 | }];
66 |
67 | // Assert.
68 | XCTAssertEqualObjects(originalDictionary, expectedDictionary);
69 | }
70 |
71 | - (void)testFlatMapDictionary {
72 | // Arrange.
73 | NSDictionary *> *originalDictionary =
74 | @{ @1 : @{@"1" : @13},
75 | @2 : @{@"2" : @42},
76 | @3 : @{} };
77 | NSArray *> *expectedArray = @[
78 | @{ @"1" : @13 },
79 | @{ @"2" : @42 }
80 | ];
81 |
82 | // Act.
83 | NSArray *> *resultingArray = [originalDictionary
84 | fbl_flatMap:^id(NSNumber *key, NSDictionary *value) {
85 | return value.count > 0 ? @{key : value} : nil;
86 | }];
87 |
88 | // Assert.
89 | XCTAssertEqualObjects(resultingArray, expectedArray);
90 | }
91 |
92 | - (void)testMapDictionary {
93 | // Arrange.
94 | NSDictionary *originalDictionary = @{ @"1" : @12, @"2" : @40, @"0" : @0 };
95 | NSArray *expectedArray = @[ @"13", @"42", (NSString *)[NSNull null] ];
96 |
97 | // Act.
98 | NSArray *resultingArray =
99 | [originalDictionary fbl_map:^id(NSString *key, NSNumber *value) {
100 | NSInteger sum = key.integerValue + value.integerValue;
101 | if (sum == 0) {
102 | return nil;
103 | }
104 | return @(sum).stringValue;
105 | }];
106 |
107 | // Assert.
108 | XCTAssertEqualObjects(resultingArray, expectedArray);
109 | }
110 |
111 | - (void)testMapValuesDictionary {
112 | // Arrange.
113 | NSDictionary *> *originalDictionary =
114 | @{ @1 : @[ @1, @12 ],
115 | @2 : @[ @2, @40 ],
116 | @3 : @[ @3 ] };
117 | NSDictionary *expectedDictionary =
118 | @{ @1 : @"13",
119 | @2 : @"42",
120 | @3 : (NSString *)[NSNull null] };
121 |
122 | // Act.
123 | NSDictionary *resultingDictionary =
124 | [originalDictionary fbl_mapValues:^id(NSArray *value) {
125 | return value.count == 2 ?
126 | @(value.firstObject.integerValue + value.lastObject.integerValue).stringValue :
127 | nil;
128 | }];
129 |
130 | // Assert.
131 | XCTAssertEqualObjects(resultingDictionary, expectedDictionary);
132 | }
133 |
134 | - (void)testZipDictionary {
135 | // Arrange.
136 | NSDictionary *dictionary1 = @{ @"1" : @12, @"2" : @40, @"0" : @0 };
137 | NSDictionary *dictionary2 = @{@"3" : @"13", @"4" : @"42"};
138 | NSUInteger expectedCount = MIN(dictionary1.count, dictionary2.count);
139 |
140 | // Act.
141 | NSArray *resultingArray = [dictionary1 fbl_zip:dictionary2];
142 |
143 | // Assert.
144 | XCTAssertEqual(resultingArray.count, expectedCount);
145 | NSArray *dict1Values = dictionary1.allValues;
146 | NSArray *dict2Values = dictionary2.allValues;
147 | for (NSArray *array in resultingArray) {
148 | XCTAssertTrue([dict1Values containsObject:array.firstObject]);
149 | XCTAssertTrue([dict2Values containsObject:array.lastObject]);
150 | }
151 | }
152 |
153 | - (void)testZipDictionaryWithDifferentContainerTypes {
154 | // Arrange.
155 | NSDictionary *dictionary = @{ @"1" : @12, @"2" : @40 };
156 | NSArray *array1 = @[ @"13", @"42", @"0" ];
157 | NSUInteger expectedCount = MIN(dictionary.count, array1.count);
158 |
159 | // Act.
160 | NSArray *resultingArray = [dictionary fbl_zip:array1];
161 |
162 | // Assert.
163 | XCTAssertEqual(resultingArray.count, expectedCount);
164 | NSArray *dictValues = dictionary.allValues;
165 | for (NSArray *array in resultingArray) {
166 | XCTAssertTrue([dictValues containsObject:array.firstObject]);
167 | XCTAssertTrue([array1 containsObject:array.lastObject]);
168 | }
169 | }
170 |
171 | @end
172 |
--------------------------------------------------------------------------------
/Tests/FBLFunctionalTests/NSOrderedSet+FBLFunctionalTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "NSOrderedSet+FBLFunctional.h"
18 |
19 | #import
20 |
21 | @interface NSOrderedSetFBLFunctionalTests : XCTestCase
22 | @end
23 |
24 | @implementation NSOrderedSetFBLFunctionalTests
25 |
26 | - (void)testFilterOrderedSet {
27 | // Arrange.
28 | NSOrderedSet *originalOrderedSet =
29 | [NSOrderedSet orderedSetWithArray:@[ @13, @42, @0 ]];
30 | NSArray *expectedArray = @[ @13, @42 ];
31 |
32 | // Act.
33 | NSOrderedSet *resultingSet = [originalOrderedSet fbl_filter:^BOOL(NSNumber *value) {
34 | return value.integerValue > 0;
35 | }];
36 |
37 | // Assert.
38 | XCTAssertEqualObjects(resultingSet, [NSOrderedSet orderedSetWithArray:expectedArray]);
39 | }
40 |
41 | - (void)testFirstOrderedSet {
42 | // Arrange.
43 | NSOrderedSet *originalOrderedSet =
44 | [NSOrderedSet orderedSetWithArray:@[ @13, @42, @100 ]];
45 | NSNumber *expectedValue = @42;
46 |
47 | // Act.
48 | NSNumber *resultingValue = [originalOrderedSet fbl_first:^BOOL(NSNumber *value) {
49 | return value.integerValue > 20;
50 | }];
51 |
52 | // Assert.
53 | XCTAssertEqualObjects(resultingValue, expectedValue);
54 | }
55 |
56 | - (void)testFlatMapOrderedSet {
57 | // Arrange.
58 | NSOrderedSet *> *originalOrderedSet =
59 | [NSOrderedSet orderedSetWithArray:@[
60 | [NSOrderedSet orderedSetWithArray:@[ @13, @42 ]],
61 | [NSOrderedSet orderedSetWithArray:@[ @14, @43 ]], [NSOrderedSet orderedSetWithArray:@[]]
62 | ]];
63 | NSArray *expectedArray = @[ @13, @42, @14, @43 ];
64 |
65 | // Act.
66 | NSArray *resultingArray =
67 | [originalOrderedSet fbl_flatMap:^id(NSOrderedSet *value) {
68 | return value.count > 0 ? value : nil;
69 | }];
70 |
71 | // Assert.
72 | XCTAssertEqualObjects(resultingArray, expectedArray);
73 | }
74 |
75 | - (void)testForEachOrderedSet {
76 | // Arrange.
77 | NSOrderedSet *originalOrderedSet =
78 | [NSOrderedSet orderedSetWithArray:@[ @13, @42, @100 ]];
79 | NSMutableArray *expectedArray = [[NSMutableArray alloc] init];
80 |
81 | // Act.
82 | [originalOrderedSet fbl_forEach:^(NSNumber *value) {
83 | [expectedArray addObject:value];
84 | }];
85 |
86 | // Assert.
87 | XCTAssertEqualObjects(originalOrderedSet, [NSOrderedSet orderedSetWithArray:expectedArray]);
88 | }
89 |
90 | - (void)testMapOrderedSet {
91 | // Arrange.
92 | NSOrderedSet *originalOrderedSet =
93 | [NSOrderedSet orderedSetWithArray:@[ @13, @42, @0 ]];
94 | NSArray *expectedArray = @[ @"13", @"42", (NSString *)[NSNull null] ];
95 |
96 | // Act.
97 | NSArray *resultingArray = [originalOrderedSet fbl_map:^id(NSNumber *value) {
98 | if (value.integerValue == 0) {
99 | return nil;
100 | }
101 | return value.stringValue;
102 | }];
103 |
104 | // Assert.
105 | XCTAssertEqualObjects(resultingArray, expectedArray);
106 | }
107 |
108 | - (void)testReduceOrderedSet {
109 | // Arrange.
110 | NSOrderedSet *originalOrderedSet =
111 | [NSOrderedSet orderedSetWithArray:@[ @13, @42, @100 ]];
112 | NSNumber *expectedValue = @(13 + 42 + 100);
113 |
114 | // Act.
115 | NSNumber *resultingValue =
116 | [originalOrderedSet fbl_reduce:@0
117 | combine:^NSNumber *(NSNumber *accumulator, NSNumber *value) {
118 | return @(accumulator.integerValue + value.integerValue);
119 | }];
120 |
121 | // Assert.
122 | XCTAssertEqualObjects(resultingValue, expectedValue);
123 | }
124 |
125 | - (void)testZipOrderedSet {
126 | // Arrange.
127 | NSOrderedSet *orderedSet1 = [NSOrderedSet orderedSetWithArray:@[ @13, @42 ]];
128 | NSOrderedSet *orderedSet2 =
129 | [NSOrderedSet orderedSetWithArray:@[ @"100", @"14", @"43" ]];
130 | NSArray *expectedArray = @[ @[ @13, @"100" ], @[ @42, @"14" ] ];
131 |
132 | // Act.
133 | NSArray *resultingArray = [orderedSet1 fbl_zip:orderedSet2];
134 |
135 | // Assert.
136 | XCTAssertEqualObjects(resultingArray, expectedArray);
137 | }
138 |
139 | - (void)testZipOrderedSetWithDifferentContainerTypes {
140 | // Arrange.
141 | NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:@[ @13, @42 ]];
142 | NSSet *set = [NSSet setWithArray:@[ @14, @43, @100 ]];
143 | NSUInteger expectedCount = MIN(orderedSet.count, set.count);
144 |
145 | // Act.
146 | NSArray *resultingArray = [orderedSet fbl_zip:set];
147 |
148 | // Assert.
149 | XCTAssertEqual(resultingArray.count, expectedCount);
150 | for (NSArray *array in resultingArray) {
151 | XCTAssertTrue([orderedSet containsObject:array.firstObject]);
152 | XCTAssertTrue([set containsObject:array.lastObject]);
153 | }
154 | }
155 |
156 | @end
157 |
--------------------------------------------------------------------------------
/Tests/FBLFunctionalTests/NSSet+FBLFunctionalTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright 2018 Google Inc. All rights reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at:
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "NSSet+FBLFunctional.h"
18 |
19 | #import
20 |
21 | @interface NSSetFBLFunctionalTests : XCTestCase
22 | @end
23 |
24 | @implementation NSSetFBLFunctionalTests
25 |
26 | - (void)testFilterSet {
27 | // Arrange.
28 | NSSet *originalSet = [NSSet setWithArray:@[ @13, @42, @0 ]];
29 | NSArray *expectedArray = @[ @13, @42 ];
30 |
31 | // Act.
32 | NSSet *resultingSet = [originalSet fbl_filter:^BOOL(NSNumber *value) {
33 | return value.integerValue > 0;
34 | }];
35 |
36 | // Assert.
37 | XCTAssertEqualObjects(resultingSet, [NSSet setWithArray:expectedArray]);
38 | }
39 |
40 | - (void)testFirstSet {
41 | // Arrange.
42 | NSSet *originalSet = [NSSet setWithArray:@[ @13, @42, @100 ]];
43 | NSNumber *expectedValue = @42;
44 |
45 | // Act.
46 | NSNumber *resultingValue = [originalSet fbl_first:^BOOL(NSNumber *value) {
47 | return value.integerValue > 20;
48 | }];
49 |
50 | // Assert.
51 | XCTAssertEqualObjects(resultingValue, expectedValue);
52 | }
53 |
54 | - (void)testFlatMapSet {
55 | // Arrange.
56 | NSSet *> *originalSet = [NSSet setWithArray:@[
57 | [NSSet setWithArray:@[ @13, @42 ]], [NSSet setWithArray:@[ @14, @43 ]], [NSSet setWithArray:@[]]
58 | ]];
59 | NSArray *expectedArray = @[ @13, @42, @14, @43 ];
60 |
61 | // Act.
62 | NSArray *resultingArray = [originalSet fbl_flatMap:^id(NSSet *value) {
63 | return value.count > 0 ? value : nil;
64 | }];
65 |
66 | // Assert.
67 | XCTAssertEqualObjects([NSSet setWithArray:resultingArray], [NSSet setWithArray:expectedArray]);
68 | }
69 |
70 | - (void)testForEachSet {
71 | // Arrange.
72 | NSSet *originalSet = [NSSet setWithArray:@[ @13, @42, @100 ]];
73 | NSMutableArray *expectedArray = [[NSMutableArray alloc] init];
74 |
75 | // Act.
76 | [originalSet fbl_forEach:^(NSNumber *value) {
77 | [expectedArray addObject:value];
78 | }];
79 |
80 | // Assert.
81 | XCTAssertEqualObjects(originalSet, [NSSet setWithArray:expectedArray]);
82 | }
83 |
84 | - (void)testMapSet {
85 | // Arrange.
86 | NSSet *originalSet = [NSSet setWithArray:@[ @13, @42, @0 ]];
87 | NSArray *expectedArray = @[ @"13", @"42", (NSString *)[NSNull null] ];
88 |
89 | // Act.
90 | NSArray *resultingArray = [originalSet fbl_map:^id(NSNumber *value) {
91 | if (value.integerValue == 0) {
92 | return nil;
93 | }
94 | return value.stringValue;
95 | }];
96 |
97 | // Assert.
98 | XCTAssertEqualObjects([NSSet setWithArray:resultingArray], [NSSet setWithArray:expectedArray]);
99 | }
100 |
101 | - (void)testReduceSet {
102 | // Arrange.
103 | NSSet *originalSet = [NSSet setWithArray:@[ @13, @42, @100 ]];
104 | NSNumber *expectedValue = @(13 + 42 + 100);
105 |
106 | // Act.
107 | NSNumber *resultingValue =
108 | [originalSet fbl_reduce:@0
109 | combine:^NSNumber *(NSNumber *accumulator, NSNumber *value) {
110 | return @(accumulator.integerValue + value.integerValue);
111 | }];
112 |
113 | // Assert.
114 | XCTAssertEqualObjects(resultingValue, expectedValue);
115 | }
116 |
117 | - (void)testZipSet {
118 | // Arrange.
119 | NSSet *set1 = [NSSet setWithArray:@[ @13, @42 ]];
120 | NSSet *set2 = [NSSet setWithArray:@[ @"100", @"14", @"43" ]];
121 | NSUInteger expectedCount = MIN(set1.count, set2.count);
122 |
123 | // Act.
124 | NSArray *resultingArray = [set1 fbl_zip:set2];
125 |
126 | // Assert.
127 | XCTAssertEqual(resultingArray.count, expectedCount);
128 | for (NSArray *array in resultingArray) {
129 | XCTAssertTrue([set1 containsObject:array.firstObject]);
130 | XCTAssertTrue([set2 containsObject:array.lastObject]);
131 | }
132 | }
133 |
134 | - (void)testZipSetWithDifferentContainerTypes {
135 | // Arrange.
136 | NSSet *set = [NSSet setWithArray:@[ @13, @42 ]];
137 | NSArray *array = @[ @"100", @"14", @"43" ];
138 | NSUInteger expectedCount = MIN(set.count, array.count);
139 |
140 | // Act.
141 | NSArray *resultingArray = [set fbl_zip:array];
142 |
143 | // Assert.
144 | XCTAssertEqual(resultingArray.count, expectedCount);
145 | for (NSArray *array in resultingArray) {
146 | XCTAssertTrue([set containsObject:array.firstObject]);
147 | XCTAssertTrue([array containsObject:array.lastObject]);
148 | }
149 | }
150 |
151 | @end
152 |
--------------------------------------------------------------------------------
/WORKSPACE:
--------------------------------------------------------------------------------
1 | git_repository(
2 | name = "bazel_skylib",
3 | remote = "https://github.com/bazelbuild/bazel-skylib.git",
4 | tag = "0.5.0",
5 | )
6 |
7 | git_repository(
8 | name = "build_bazel_rules_apple",
9 | remote = "https://github.com/bazelbuild/rules_apple.git",
10 | tag = "0.6.0",
11 | )
12 |
13 | git_repository(
14 | name = "build_bazel_rules_swift",
15 | remote = "https://github.com/bazelbuild/rules_swift.git",
16 | tag = "0.2.0",
17 | )
18 |
19 | http_file(
20 | name = "xctestrunner",
21 | executable = 1,
22 | url = "https://github.com/google/xctestrunner/releases/download/0.2.3/ios_test_runner.par",
23 | )
24 |
--------------------------------------------------------------------------------