fun-ruby 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +42 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +42 -0
- data/.ruby-version +1 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +61 -0
- data/LICENSE.txt +21 -0
- data/Makefile +5 -0
- data/README.md +19 -0
- data/Rakefile +16 -0
- data/bin/console +16 -0
- data/bin/rake +29 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/setup +8 -0
- data/bin/yard +29 -0
- data/bin/yardoc +29 -0
- data/bin/yri +29 -0
- data/fun-ruby.gemspec +35 -0
- data/lib/fun-ruby.rb +4 -0
- data/lib/fun_ruby/all.rb +8 -0
- data/lib/fun_ruby/array.rb +63 -0
- data/lib/fun_ruby/common/helpers.rb +19 -0
- data/lib/fun_ruby/container/define.rb +66 -0
- data/lib/fun_ruby/container/mixin.rb +28 -0
- data/lib/fun_ruby/container/resolve.rb +57 -0
- data/lib/fun_ruby/container.rb +55 -0
- data/lib/fun_ruby/enum.rb +214 -0
- data/lib/fun_ruby/file.rb +32 -0
- data/lib/fun_ruby/function.rb +157 -0
- data/lib/fun_ruby/hash.rb +559 -0
- data/lib/fun_ruby/string.rb +72 -0
- data/lib/fun_ruby/version.rb +5 -0
- data/lib/fun_ruby.rb +87 -0
- metadata +165 -0
@@ -0,0 +1,559 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FunRuby
|
4
|
+
# Module containing methods for hashes
|
5
|
+
module Hash
|
6
|
+
include Common::Helpers
|
7
|
+
|
8
|
+
extend self
|
9
|
+
|
10
|
+
# Returns a value stored by a given key.
|
11
|
+
# If there is no given key it return a default value
|
12
|
+
#
|
13
|
+
# @since 0.1.0
|
14
|
+
#
|
15
|
+
# @param key [#hash, #eql?]
|
16
|
+
# @param hash [#to_h]
|
17
|
+
#
|
18
|
+
# @return [Object]
|
19
|
+
#
|
20
|
+
# @example Base
|
21
|
+
# hash = { age: 20, name: 'John' }
|
22
|
+
# F::Hash.get(:age, hash) # => 20
|
23
|
+
# F::Hash.get(:name, hash) # => 'John'
|
24
|
+
# F::Hash.get(:email, hash) # => nil
|
25
|
+
#
|
26
|
+
# @example Curried
|
27
|
+
# hash = { age: 20, name: 'John' }
|
28
|
+
# curried = F::Hash.get
|
29
|
+
# curried.(:age, hash) # => 20
|
30
|
+
# curried.(:name).(hash) # => 'John'
|
31
|
+
#
|
32
|
+
# @example Curried
|
33
|
+
# hash = { age: 20, name: 'John' }
|
34
|
+
# curried = F::Hash.get
|
35
|
+
# curried.(:age, hash) # => 20
|
36
|
+
# curried.(:name).(hash) # => 'John'
|
37
|
+
#
|
38
|
+
# @example Curried with placeholders
|
39
|
+
# hash = { age: 20, name: 'John' }
|
40
|
+
# curried = F::Hash.get(F._, hash)
|
41
|
+
# curried.(:age) # => 20
|
42
|
+
# curried.(:name) # => 'John'
|
43
|
+
def get(key = F._, hash = F._)
|
44
|
+
curry_implementation(:get, key, hash)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns a value stored by a given key.
|
48
|
+
# If there is no given key it raises error
|
49
|
+
#
|
50
|
+
# @since 0.1.0
|
51
|
+
#
|
52
|
+
# @param key [#hash, #eql?]
|
53
|
+
# @param hash [#to_h]
|
54
|
+
#
|
55
|
+
# @return [Object]
|
56
|
+
#
|
57
|
+
# @raise KeyError
|
58
|
+
#
|
59
|
+
# @example Base
|
60
|
+
# hash = { age: 20, name: 'John' }
|
61
|
+
# F::Hash.fetch(:age, hash) # => 20
|
62
|
+
# F::Hash.fetch(:name, hash) # => 'John'
|
63
|
+
# F::Hash.fetch(:email, hash) # => raise KeyError, "key not found: :email"
|
64
|
+
#
|
65
|
+
# @example Curried
|
66
|
+
# hash = { age: 20, name: 'John' }
|
67
|
+
# curried = F::Hash.fetch
|
68
|
+
# curried.(:age, hash) # => 20
|
69
|
+
# curried.(:name).(hash) # => 'John'
|
70
|
+
# curried.(:email).(hash) # => raise KeyError, "key not found: :email"
|
71
|
+
#
|
72
|
+
# @example Curried with placeholders
|
73
|
+
# hash = { age: 20, name: 'John' }
|
74
|
+
# curried = F::Hash.fetch(F._, hash)
|
75
|
+
# curried.(:age) # => 20
|
76
|
+
# curried.(:name) # => 'John'
|
77
|
+
def fetch(key = F._, hash = F._)
|
78
|
+
curry_implementation(:fetch, key, hash)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns a value stored by a given key.
|
82
|
+
# If there is no given key it calls a given fallback.
|
83
|
+
#
|
84
|
+
# @since 0.1.0
|
85
|
+
#
|
86
|
+
# @param key [#hash, #eql?]
|
87
|
+
# @param fallback [#to_call]
|
88
|
+
# @param hash [#to_h]
|
89
|
+
#
|
90
|
+
# @return [Object]
|
91
|
+
#
|
92
|
+
# @example Base
|
93
|
+
# hash = { age: 20, name: 'John' }
|
94
|
+
# F::Hash.fetch_with(:age, ->(_) { :fallback }, hash) # => 20
|
95
|
+
# F::Hash.fetch_with(:name, ->(_) { :fallback }, hash) # => 'John'
|
96
|
+
# F::Hash.fetch_with(:email, ->(_) { :fallback }, hash) # => :fallback
|
97
|
+
#
|
98
|
+
# @example Curried
|
99
|
+
# hash = { age: 20, name: 'John' }
|
100
|
+
# curried = F::Hash.fetch_with
|
101
|
+
# curried.(:age, ->(_) { :fallback }, hash) # => 20
|
102
|
+
# curried.(:name).(->(_) { :fallback }).(hash) # => 'John'
|
103
|
+
# curried.(:email).(->(_) { :fallback }).(hash) # => :fallback
|
104
|
+
#
|
105
|
+
# @example Curried with placeholders
|
106
|
+
# hash = { age: 20, name: 'John' }
|
107
|
+
# curried = F::Hash.fetch_with(F._, F._, F._)
|
108
|
+
# curried.(:age).(->(_) { :fallback }).(hash) # => 20
|
109
|
+
#
|
110
|
+
# curried = F::Hash.fetch_with(F._, ->(_) { :fallback }, F._)
|
111
|
+
# curried.(:age).(hash) # => 20
|
112
|
+
# curried.(:email).(hash) # => :fallback
|
113
|
+
def fetch_with(key = F._, fallback = F._, hash = F._)
|
114
|
+
curry_implementation(:fetch_with, key, fallback, hash)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Puts a value by a given key.
|
118
|
+
# If the key is already taken the current value will be replaced.
|
119
|
+
#
|
120
|
+
# @since 0.1.0
|
121
|
+
#
|
122
|
+
# @param key [#hash, #eql?]
|
123
|
+
# @param value [Object]
|
124
|
+
# @param hash [#to_h]
|
125
|
+
#
|
126
|
+
# @return [Hash]
|
127
|
+
#
|
128
|
+
# @example Base
|
129
|
+
# hash = { name: "John" }
|
130
|
+
# F::Hash.put(:age, 20, hash) # => { name: "John", age: 20 }
|
131
|
+
# F::Hash.put(:name, "Peter", hash) # => { name: "Peter" }
|
132
|
+
#
|
133
|
+
# @example Curried
|
134
|
+
# hash = { name: "John" }
|
135
|
+
# curried = F::Hash.put
|
136
|
+
# curried.(:age).(20).(hash) # => { name: "John", age: 20 }
|
137
|
+
# curried.(:name).("Peter").(hash) # => { name: "Peter" }
|
138
|
+
#
|
139
|
+
# @example Curried with placeholders
|
140
|
+
# hash = { name: "John" }
|
141
|
+
# curried = F::Hash.put(F._, 20, hash)
|
142
|
+
# curried.(:age) # => { name: "John", age: 20 }
|
143
|
+
#
|
144
|
+
# curried = F::Hash.put(F._, 20, F._)
|
145
|
+
# curried.(:age).(hash) # => { name: "John", age: 20 }
|
146
|
+
#
|
147
|
+
# curried = F::Hash.put(:age, F._, hash)
|
148
|
+
# curried.(20) # => { name: "John", age: 20 }
|
149
|
+
def put(key = F._, value = F._, hash = F._)
|
150
|
+
curry_implementation(:put, key, value, hash)
|
151
|
+
end
|
152
|
+
|
153
|
+
# Merges two hashes. The key-value pairs from the second to the first.
|
154
|
+
# If the key is already taken the current value will be replaced.
|
155
|
+
#
|
156
|
+
# @since 0.1.0
|
157
|
+
#
|
158
|
+
# @param first [#to_h]
|
159
|
+
# @param second [#to_h]
|
160
|
+
#
|
161
|
+
# @return [Hash]
|
162
|
+
#
|
163
|
+
# @example Base
|
164
|
+
# first = { name: "John" }
|
165
|
+
# second = { age: 20 }
|
166
|
+
# F::Hash.merge(first, second) # => { name: "John", age: 20 }
|
167
|
+
#
|
168
|
+
# first = { name: "John" }
|
169
|
+
# second = { name: "Bill", age: 20 }
|
170
|
+
# F::Hash.merge(first, second) # => { name: "Bill", age: 20 }
|
171
|
+
#
|
172
|
+
# @example Curried
|
173
|
+
# first = { name: "John" }
|
174
|
+
# second = { age: 20 }
|
175
|
+
# curried = F::Hash.merge
|
176
|
+
# curried.(first).(second) # => { name: "John", age: 20 }
|
177
|
+
#
|
178
|
+
# first = { name: "John" }
|
179
|
+
# second = { name: "Bill", age: 20 }
|
180
|
+
# curried = F::Hash.merge
|
181
|
+
# curried.(first).(second) # => { name: "Bill", age: 20 }
|
182
|
+
#
|
183
|
+
# @example Curried with placeholders
|
184
|
+
# first = { name: "John" }
|
185
|
+
# second = { age: 20 }
|
186
|
+
# curried = F::Hash.merge(F._, F._)
|
187
|
+
# curried.(first).(second) # => { name: "John", age: 20 }
|
188
|
+
#
|
189
|
+
# first = { name: "John" }
|
190
|
+
# second = { name: "Bill", age: 20 }
|
191
|
+
# curried = F::Hash.merge(F._, second)
|
192
|
+
# curried.(first) # => { name: "Bill", age: 20 }
|
193
|
+
def merge(first = F._, second = F._)
|
194
|
+
curry_implementation(:merge, first, second)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Builds a new hash with only given keys from a given hash.
|
198
|
+
# If keys are missed in the given hash the corresponded key will be absent
|
199
|
+
# in the result hash.
|
200
|
+
#
|
201
|
+
# @since 0.1.0
|
202
|
+
#
|
203
|
+
# @param keys [::Array of (#hash, #eql?)]
|
204
|
+
# @param hash [#to_h]
|
205
|
+
#
|
206
|
+
# @return [Hash]
|
207
|
+
#
|
208
|
+
# @example Base
|
209
|
+
# hash = { name: "John", age: 20, email: "john@gmail.com", country: "USA" }
|
210
|
+
#
|
211
|
+
# F::Hash.slice([:name, :age, :country], hash) # => { name: "John", age: 20, country: "USA" }
|
212
|
+
# F::Hash.slice([:name, :age, :address], hash) # => { name: "John", age: 20 }
|
213
|
+
#
|
214
|
+
# @example Curried
|
215
|
+
# hash = { name: "John", age: 20, email: "john@gmail.com", country: "USA" }
|
216
|
+
# curried = F::Hash.slice
|
217
|
+
#
|
218
|
+
# curried.([:name, :age, :country]).(hash) # => { name: "John", age: 20, country: "USA" }
|
219
|
+
# curried.([:name, :age, :address]).(hash) # => { name: "John", age: 20 }
|
220
|
+
#
|
221
|
+
# @example Curried with placeholders
|
222
|
+
# hash = { name: "John", age: 20, email: "john@gmail.com", country: "USA" }
|
223
|
+
#
|
224
|
+
# curried = F::Hash.slice(F._, hash)
|
225
|
+
# curried.([:name, :age, :country]) # => { name: "John", age: 20, country: "USA" }
|
226
|
+
# curried.([:name, :age, :address]) # => { name: "John", age: 20 }
|
227
|
+
def slice(keys = F._, hash = F._)
|
228
|
+
curry_implementation(:slice, keys, hash)
|
229
|
+
end
|
230
|
+
|
231
|
+
# Builds a new hash with only given keys from a given hash.
|
232
|
+
# If keys are missed in the given hash KeyError is raised
|
233
|
+
#
|
234
|
+
# @since 0.1.0
|
235
|
+
#
|
236
|
+
# @param keys [::Array of (#hash, #eql?)]
|
237
|
+
# @param hash [#to_h]
|
238
|
+
#
|
239
|
+
# @return [Hash]
|
240
|
+
#
|
241
|
+
# @example Base
|
242
|
+
# hash = { name: "John", age: 20, country: "USA" }
|
243
|
+
#
|
244
|
+
# F::Hash.slice!([:name, :age, :country], hash) # => { name: "John", age: 20, country: "USA" }
|
245
|
+
# F::Hash.slice!([:address, :email], hash) # => raise KeyError, "keys not found: [:address, :email]"
|
246
|
+
def slice!(keys = F._, hash = F._)
|
247
|
+
curry_implementation(:slice!, keys, hash)
|
248
|
+
end
|
249
|
+
|
250
|
+
# Returns an array of values stored by given keys
|
251
|
+
# If any key is missed in the given hash KeyError is raised with the first missed key
|
252
|
+
#
|
253
|
+
# @since 0.1.0
|
254
|
+
#
|
255
|
+
# @param keys [::Array of (#hash, #eql?)]
|
256
|
+
# @param hash [#to_h]
|
257
|
+
#
|
258
|
+
# @return [::Array[Object]]
|
259
|
+
#
|
260
|
+
# @example Base
|
261
|
+
# hash = { name: "John", age: 20, country: "USA" }
|
262
|
+
#
|
263
|
+
# F::Hash.fetch_values([:name, :age, :country], hash) # => ["John", 20, "USA"]
|
264
|
+
# F::Hash.fetch_values([:address, :email], hash) # => raise KeyError, "key not found: :address"
|
265
|
+
def fetch_values(keys = F._, hash = F._)
|
266
|
+
curry_implementation(:fetch_values, keys, hash)
|
267
|
+
end
|
268
|
+
|
269
|
+
# Returns an array of values stored by given keys
|
270
|
+
# If a key is missed the default value is returned
|
271
|
+
#
|
272
|
+
# @since 0.1.0
|
273
|
+
#
|
274
|
+
# @param keys [::Array of (#hash, #eql?)]
|
275
|
+
# @param hash [#to_h]
|
276
|
+
#
|
277
|
+
# @return [::Array[Object]]
|
278
|
+
#
|
279
|
+
# @example Base
|
280
|
+
# hash = { name: "John", age: 20, country: "USA" }
|
281
|
+
#
|
282
|
+
# F::Hash.values_at([:name, :age, :country], hash) # => ["John", 20, "USA"]
|
283
|
+
# F::Hash.values_at([:address, :email, :country, :age], hash) # => [nil, nil, "USA", 20]
|
284
|
+
def values_at(keys = F._, hash = F._)
|
285
|
+
curry_implementation(:values_at, keys, hash)
|
286
|
+
end
|
287
|
+
|
288
|
+
# Returns an array of all stored values
|
289
|
+
#
|
290
|
+
# @since 0.1.0
|
291
|
+
#
|
292
|
+
# @param hash [#to_h]
|
293
|
+
#
|
294
|
+
# @return [::Array[Object]]
|
295
|
+
#
|
296
|
+
# @example Base
|
297
|
+
# F::Hash.values({}) # => []
|
298
|
+
# F::Hash.values({ age: 33 }) # => [33]
|
299
|
+
# F::Hash.values({ age: 33, name: "John"}) # => [33, "John"]
|
300
|
+
def values(hash = F._)
|
301
|
+
curry_implementation(:values, hash)
|
302
|
+
end
|
303
|
+
|
304
|
+
# Returns an array of all stored keys
|
305
|
+
#
|
306
|
+
# @since 0.1.0
|
307
|
+
#
|
308
|
+
# @param hash [#to_h]
|
309
|
+
#
|
310
|
+
# @return [::Array[Object]]
|
311
|
+
#
|
312
|
+
# @example Base
|
313
|
+
# F::Hash.keys({}) # => []
|
314
|
+
# F::Hash.keys({ age: 33 }) # => [:age]
|
315
|
+
# F::Hash.keys({ age: 33, name: "John"}) # => [:age, :name]
|
316
|
+
def keys(hash = F._)
|
317
|
+
curry_implementation(:keys, hash)
|
318
|
+
end
|
319
|
+
|
320
|
+
# Returns a new hash containing only pairs
|
321
|
+
# for which a given function returns true
|
322
|
+
#
|
323
|
+
# @since 0.1.0
|
324
|
+
#
|
325
|
+
# @param function [#call/2]
|
326
|
+
# @param hash [#to_h]
|
327
|
+
#
|
328
|
+
# @return [::Array[Object]]
|
329
|
+
#
|
330
|
+
# @example Base
|
331
|
+
# hash = { 'a' => 1, 'b' => 2, :c => 3, :d => 4 }
|
332
|
+
# F::Hash.select(->(key, _value) { key.is_a?(String) }, hash) # => { 'a' => 1, 'b' => 2 }
|
333
|
+
# F::Hash.select(->(_key, value) { value.odd? }, hash) # => { 'a' => 1, :c => 3 }
|
334
|
+
def select(function = F._, hash = F._)
|
335
|
+
curry_implementation(:select, function, hash)
|
336
|
+
end
|
337
|
+
|
338
|
+
# Returns a new hash excluding pairs
|
339
|
+
# for which a given function returns true
|
340
|
+
#
|
341
|
+
# @since 0.1.0
|
342
|
+
#
|
343
|
+
# @param function [#call/2]
|
344
|
+
# @param hash [#to_h]
|
345
|
+
#
|
346
|
+
# @return [::Array[Object]]
|
347
|
+
#
|
348
|
+
# @example Base
|
349
|
+
# hash = { 'a' => 1, 'b' => 2, :c => 3, :d => 4 }
|
350
|
+
# F::Hash.reject(->(key, _value) { key.is_a?(String) }, hash) # => { :c => 3, :d => 4 }
|
351
|
+
# F::Hash.reject(->(_key, value) { value.odd? }, hash) # => { 'b' => 2, :d =>4 }
|
352
|
+
def reject(function = F._, hash = F._)
|
353
|
+
curry_implementation(:reject, function, hash)
|
354
|
+
end
|
355
|
+
|
356
|
+
# Returns a value stored by a given chain of keys.
|
357
|
+
# If a value of any level key of the chain is not found nil is returned.
|
358
|
+
#
|
359
|
+
# @since 0.1.0
|
360
|
+
#
|
361
|
+
# @param keys [::Array of (#hash, #eql?)]
|
362
|
+
# @param hash [#to_h]
|
363
|
+
# @return [::Array[Object]]
|
364
|
+
#
|
365
|
+
# @example Base
|
366
|
+
# hash = { a: { b: { c: 3 } } }
|
367
|
+
# F::Hash.dig([:a], hash) # => { b: { c: 3 } }
|
368
|
+
# F::Hash.dig([:a, :b], hash) # => { c: 3 }
|
369
|
+
# F::Hash.dig([:a, :b, :c], hash) # => 3
|
370
|
+
# F::Hash.dig([:foo], hash) # => nil
|
371
|
+
# F::Hash.dig([:a, :foo], hash) # => nil
|
372
|
+
# F::Hash.dig([:a, :b, :foo], hash) # => nil
|
373
|
+
def dig(keys = F._, hash = F._)
|
374
|
+
curry_implementation(:dig, keys, hash)
|
375
|
+
end
|
376
|
+
|
377
|
+
# Returns a value stored by a given chain of keys.
|
378
|
+
# If a value of any level key of the chain is not found KeyError is raised
|
379
|
+
#
|
380
|
+
# @since 0.1.0
|
381
|
+
#
|
382
|
+
# @param keys [::Array of (#hash, #eql?)]
|
383
|
+
# @param hash [#to_h]
|
384
|
+
# @return [::Array[Object]]
|
385
|
+
#
|
386
|
+
# @example Base
|
387
|
+
# hash = { a: { b: { c: 3 } } }
|
388
|
+
# F::Hash.dig!([:a], hash) # => { b: { c: 3 } }
|
389
|
+
# F::Hash.dig!([:a, :b], hash) # => { c: 3 }
|
390
|
+
# F::Hash.dig!([:a, :b, :c], hash) # => 3
|
391
|
+
# F::Hash.dig!([:foo], hash) # => raise KeyError, "key not found: :foo"
|
392
|
+
# F::Hash.dig!([:a, :foo], hash) # => raise KeyError, "key not found: :foo"
|
393
|
+
# F::Hash.dig!([:a, :b, :foo], hash) # => raise KeyError, "key not found: :foo"
|
394
|
+
def dig!(keys = F._, hash = F._)
|
395
|
+
curry_implementation(:dig!, keys, hash)
|
396
|
+
end
|
397
|
+
|
398
|
+
# Returns a new hash without all key-valued pairs
|
399
|
+
#
|
400
|
+
# @since 0.1.0
|
401
|
+
#
|
402
|
+
# @param hash [#to_h]
|
403
|
+
#
|
404
|
+
# @example Base
|
405
|
+
# hash = { name: "John", age: 18, email: nil, country: nil }
|
406
|
+
# F::Hash.compact(hash) # => { name: "John", age: 18 }
|
407
|
+
def compact(keys = F._, hash = F._)
|
408
|
+
curry_implementation(:compact, keys, hash)
|
409
|
+
end
|
410
|
+
|
411
|
+
# Returns a new hash with updated keys calculated
|
412
|
+
# as a result returned from a given function
|
413
|
+
#
|
414
|
+
# @since 0.1.0
|
415
|
+
#
|
416
|
+
# @param function [#call/1]
|
417
|
+
# @param hash [#to_h]
|
418
|
+
#
|
419
|
+
# @example Base
|
420
|
+
# hash = { a: 1, b: 2, c: 3 }
|
421
|
+
# F::Hash.transform_keys(->(key) { key.to_s }, hash) #=> { 'a' => 1, 'b' => 2, 'c' => 3 }
|
422
|
+
def transform_keys(function = F._, hash = F._)
|
423
|
+
curry_implementation(:transform_keys, function, hash)
|
424
|
+
end
|
425
|
+
|
426
|
+
# Returns a new hash with updated values calculated
|
427
|
+
# as a result returned from a given function
|
428
|
+
#
|
429
|
+
# @since 0.1.0
|
430
|
+
#
|
431
|
+
# @param function [#call/1]
|
432
|
+
# @param hash [#to_h]
|
433
|
+
#
|
434
|
+
# @example Base
|
435
|
+
# hash = { a: 1, b: 2, c: 3 }
|
436
|
+
# F::Hash.transform_values(->(value) { value.to_s }, hash) #=> { a: '1', b: '2', c: '3' }
|
437
|
+
def transform_values(function = F._, hash = F._)
|
438
|
+
curry_implementation(:transform_values, function, hash)
|
439
|
+
end
|
440
|
+
|
441
|
+
private
|
442
|
+
|
443
|
+
def _get(key, hash)
|
444
|
+
_hash(hash)[key]
|
445
|
+
end
|
446
|
+
|
447
|
+
def _fetch(key, hash)
|
448
|
+
_hash(hash).fetch(key)
|
449
|
+
end
|
450
|
+
|
451
|
+
def _fetch_with(key, fallback, hash)
|
452
|
+
_hash(hash).fetch(key, &fallback)
|
453
|
+
end
|
454
|
+
|
455
|
+
def _put(key, value, hash)
|
456
|
+
_hash(hash).merge(key => value)
|
457
|
+
end
|
458
|
+
|
459
|
+
def _merge(first, second)
|
460
|
+
_hash(first).merge(_hash(second))
|
461
|
+
end
|
462
|
+
|
463
|
+
if RUBY_VERSION >= "2.5"
|
464
|
+
def _slice(keys, hash)
|
465
|
+
_hash(hash).slice(*keys)
|
466
|
+
end
|
467
|
+
else
|
468
|
+
def _slice(keys, hash)
|
469
|
+
hash = _hash(hash)
|
470
|
+
keys.each_with_object({}) do |key, new_hash|
|
471
|
+
new_hash[key] = hash[key] if hash.key?(key)
|
472
|
+
end
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
def _slice!(keys, hash)
|
477
|
+
hash = _hash(hash)
|
478
|
+
missed_keys = keys - hash.keys
|
479
|
+
raise KeyError, "keys not found: #{missed_keys.inspect}" if missed_keys.any?
|
480
|
+
|
481
|
+
_slice(keys, hash)
|
482
|
+
end
|
483
|
+
|
484
|
+
def _fetch_values(keys, hash)
|
485
|
+
_hash(hash).fetch_values(*keys)
|
486
|
+
end
|
487
|
+
|
488
|
+
def _values_at(keys, hash)
|
489
|
+
_hash(hash).values_at(*keys)
|
490
|
+
end
|
491
|
+
|
492
|
+
def _values(hash)
|
493
|
+
_hash(hash).values
|
494
|
+
end
|
495
|
+
|
496
|
+
def _keys(hash)
|
497
|
+
_hash(hash).keys
|
498
|
+
end
|
499
|
+
|
500
|
+
def _select(function, hash)
|
501
|
+
_hash(hash).select(&function)
|
502
|
+
end
|
503
|
+
|
504
|
+
def _reject(function, hash)
|
505
|
+
_hash(hash).reject(&function)
|
506
|
+
end
|
507
|
+
|
508
|
+
def _dig(keys, hash)
|
509
|
+
_hash(hash).dig(*keys)
|
510
|
+
end
|
511
|
+
|
512
|
+
def _dig!(keys, hash)
|
513
|
+
hash = _hash(hash)
|
514
|
+
keys.reduce(hash) { |current, key| current.fetch(key) }
|
515
|
+
end
|
516
|
+
|
517
|
+
if RUBY_VERSION >= "2.4"
|
518
|
+
def _compact(hash)
|
519
|
+
_hash(hash).compact
|
520
|
+
end
|
521
|
+
else
|
522
|
+
def _compact(hash)
|
523
|
+
_hash(hash).reject { |_key, value| value.nil? }
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
if RUBY_VERSION >= "2.5"
|
528
|
+
def _transform_keys(function, hash)
|
529
|
+
_hash(hash).transform_keys(&function)
|
530
|
+
end
|
531
|
+
else
|
532
|
+
def _transform_keys(function, hash)
|
533
|
+
hash = _hash(hash)
|
534
|
+
hash.each_with_object({}) do |(key, value), new_hash|
|
535
|
+
new_key = function.(key)
|
536
|
+
new_hash[new_key] = value
|
537
|
+
end
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
if RUBY_VERSION >= "2.4"
|
542
|
+
def _transform_values(function, hash)
|
543
|
+
_hash(hash).transform_values(&function)
|
544
|
+
end
|
545
|
+
else
|
546
|
+
def _transform_values(function, hash)
|
547
|
+
hash = _hash(hash)
|
548
|
+
hash.each_with_object({}) do |(key, value), new_hash|
|
549
|
+
new_value = function.(value)
|
550
|
+
new_hash[key] = new_value
|
551
|
+
end
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
def _hash(hash)
|
556
|
+
hash.to_h
|
557
|
+
end
|
558
|
+
end
|
559
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "common/helpers"
|
4
|
+
|
5
|
+
module FunRuby
|
6
|
+
# Module containing methods for strings
|
7
|
+
module String
|
8
|
+
include Common::Helpers
|
9
|
+
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# Split a string by a passed delimiter
|
13
|
+
#
|
14
|
+
# @since 0.1.0
|
15
|
+
#
|
16
|
+
# @param splitter [::Array|::Regexp]
|
17
|
+
# @param string [::String]
|
18
|
+
#
|
19
|
+
# @return [::Array[::String]]
|
20
|
+
#
|
21
|
+
# @example Basics
|
22
|
+
# F::String.split("+", "1+2+3") #=> ["1", "2", "3"]
|
23
|
+
#
|
24
|
+
# @example Curried
|
25
|
+
# curried = F::String.split
|
26
|
+
# curried.("+").("1+2+3") #=> ["1", "2", "3"]
|
27
|
+
#
|
28
|
+
# @example Curried with placeholder
|
29
|
+
# curried = F::String.split(F._, "1+2+3")
|
30
|
+
# curried.("+") #=> ["1", "2", "3"]
|
31
|
+
def split(splitter = F._, string = F._)
|
32
|
+
curry_implementation(:split, splitter, string)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Concats a string by a passed delimiter
|
36
|
+
#
|
37
|
+
# @since 0.1.0
|
38
|
+
#
|
39
|
+
# @param first [::String]
|
40
|
+
# @param second [::String]
|
41
|
+
#
|
42
|
+
# @return [::String]
|
43
|
+
#
|
44
|
+
# @example Basics
|
45
|
+
# F::String.concat("123", "456") #=> "123456"
|
46
|
+
#
|
47
|
+
# @example Curried
|
48
|
+
# curried = F::String.concat
|
49
|
+
# curried.("123").("456") #=> "123456"
|
50
|
+
#
|
51
|
+
# @example Curried with placeholder
|
52
|
+
# curried = F::String.concat(F._, "456")
|
53
|
+
# curried.("123") #=> "123456"
|
54
|
+
def concat(first = F._, second = F._)
|
55
|
+
curry_implementation(:concat, first, second)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def _split(splitter, string)
|
61
|
+
_string(string).split(splitter)
|
62
|
+
end
|
63
|
+
|
64
|
+
def _concat(first, second)
|
65
|
+
_string(first) + _string(second)
|
66
|
+
end
|
67
|
+
|
68
|
+
def _string(string)
|
69
|
+
string.to_s
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|