blank_empty_nil_filters 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 31f1a60dad0e7ba230e21358acf7a044d79852ac
4
- data.tar.gz: 7ace2d848b525742ba194b7300e21ef1716a6366
2
+ SHA256:
3
+ metadata.gz: adbf79bbbb71e8dfed6243cf91759f9279b3970ad269e0f861c36172920b1e23
4
+ data.tar.gz: 695e3e289ad0548df29683d72cc0b254ce8772b7450eb7dc4f09fd2f421dcf20
5
5
  SHA512:
6
- metadata.gz: 99a10a6017b9dbbeafcff7acdd8ef9d15fca64dbc638dabbf479113017533fb3ca219351b47f2f38332deec2d16de6eea2f9b9ed822e5a86d8277925ad3c65fc
7
- data.tar.gz: bf611e7b505e56e571e4bc78cd2ff61c48b49a23fe993db5773c5f46e5cb41bd16b9006f016f0d07daa6e6e6604afbb7057d02b6816935e0b00b2c799f71c0c1
6
+ metadata.gz: bc6654261141905a9f63409dffb74caea814663102401992ee3eed3b63f0a528c5cd8fc07d2f4477786f800024a6b463087b27265b3c2b50318a8ccb1ded9242
7
+ data.tar.gz: 4a14c426a1e5b5c65edf90558f8843d03bb6f293e8d55ab96ead2e301782fa3f37b4c27c2773ddb2b7a4bc8371ccaefdff8e906b6531abc49e42dd8609fe5979
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- blank_empty_nil_filters (0.1.1)
4
+ blank_empty_nil_filters (0.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -138,4 +138,4 @@ DEPENDENCIES
138
138
  yard
139
139
 
140
140
  BUNDLED WITH
141
- 2.0.1
141
+ 2.2.0.rc.1
data/README.md CHANGED
@@ -4,18 +4,29 @@ Ruby gem to extend Hash and Array with filters for blank, empty, and nil values.
4
4
 
5
5
  Build status: [![CircleCI](https://circleci.com/gh/aks/blank_empty_nil_filters/tree/master.svg?style=svg)](https://circleci.com/gh/aks/blank_empty_nil_filters/tree/master)
6
6
 
7
- This module creates new methods to be prepended to the Array, Hash, String,
8
- and Object classes to implement recursive filters for _blank_, _empty_, and
9
- nil values.
10
-
11
- Note: `ActiveSupport` provides _some_ of these methods, but in general is a *much* larger body
12
- of code. This module are only those methods related to "blank", "empty" or nil. Also,
13
- `ActiveSupport` uses `Regexp` `match` to determine blankness, while this code uses a
14
- non-destructive `strip`, which is both faster and less sensitive to non-UTF8 string error
15
- conditions.
16
-
17
- In general an _empty_ value has zero length, and a _blank_ value is either empty or has
18
- all blank values (e.g., `to_s.strip.length.zero?`)
7
+ This module creates new methods to be prepended to the Array, Hash,
8
+ String, and Object classes to implement recursive filters for _blank_,
9
+ _empty_, and nil values.
10
+
11
+ The methods can select or reject values which are blank _(whitespace)_,
12
+ empty _(zero length)_, or nil, and do so recursively.
13
+
14
+ The default behavior is to filter recursively, without limit.
15
+ However, optional arguments may be applied to any filter method to
16
+ indicate the _start_ level and the _depth_ to which filtering should
17
+ be done. This is useful if, say, a hash needs to retain its top-level
18
+ keys, regardless of whether or not its values are empty, but deeper
19
+ level hashes can be completely removed if they are empty.
20
+
21
+ Note: `ActiveSupport` provides _some_ of these methods, but in general
22
+ is a *much* larger body of code. This module are only those methods
23
+ related to "blank", "empty" or nil. Also, `ActiveSupport` uses
24
+ `Regexp` `match` to determine blankness, while this code uses a
25
+ non-destructive `strip`, which is both faster and less sensitive to
26
+ non-UTF8 string error conditions.
27
+
28
+ In general an _empty_ value has zero length, and a _blank_ value is either
29
+ empty or has all blank values (e.g., `to_s.strip.length.zero?`)
19
30
 
20
31
  In the descriptions below, `aoh` is an `Array` or `Hash` object.
21
32
 
@@ -67,6 +78,7 @@ hash.nil_value_keys # keys from nil values
67
78
  ```
68
79
 
69
80
  All of the `no_*` methods have aliases of `reject_*`. For example, `reject_empty_values`.
81
+ All of the `only_*` methods have aliases of `select_*`; eg: `select_nil_values`.
70
82
  Some folks prefer the shorter names, some prefer the longer ones. Take your pick.
71
83
 
72
84
  ```ruby
@@ -75,6 +87,19 @@ aoh.reject_blank_values # aoh.no_blank_values
75
87
  aoh.reject_nil_values # aoh.no_nil_values
76
88
  ```
77
89
 
90
+ Any of the above methods can be provided optional arguments of _start_ and _depth_
91
+ to indicate levels at which filter _(selecting or rejecting)_ should start and
92
+ stop.
93
+
94
+ ```ruby
95
+ aoh.no_empty_values(1) # no empty items at level 1 or higher; leave level 0 alone
96
+ aoh.no_blank_values(1) # no blank items at level 1 or higher; leave level 0 alone
97
+ aoh.no_nil_values(1, 4) # no nil items at level 1 until level 4; level level 0 alone
98
+ ```
99
+
100
+ Note that it is important to use a `depth` value to prevent infinite loops when there
101
+ are recursive data structures.
102
+
78
103
  All of the above methods are wrappers around two general purpose methods:
79
104
 
80
105
  ```ruby
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift File.expand_path('../lib', __FILE__)
4
+ require 'blank_empty_nil_filters/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'blank_empty_nil_filters'
8
+ s.version = BlankEmptyNilFilters::VERSION
9
+ s.authors = ['Alan Stebbens']
10
+ s.email = ['aks@stebbens.org']
11
+ s.homepage = 'https://github.com/aks/blank_empty_nil_filters'
12
+ s.licenses = ['MIT']
13
+ s.summary = 'Extensions for filtering empty, blank, and nil values from Hashes and Arrays',
14
+ s.description = <<~TEXT
15
+ Extentions for convenient filtering of blank, empty, and nil values from
16
+ Hash and Array instances.
17
+ TEXT
18
+
19
+ s.files = Dir.glob('{bin/*,lib/**/*,[A-Z]*}')
20
+ s.platform = Gem::Platform::RUBY
21
+ s.require_paths = ['lib']
22
+
23
+ s.add_development_dependency "bundler"
24
+ s.add_development_dependency "fuubar"
25
+ s.add_development_dependency "guard"
26
+ s.add_development_dependency "guard-rspec"
27
+ s.add_development_dependency "guard-yard"
28
+ s.add_development_dependency "pry-byebug"
29
+ s.add_development_dependency "rake"
30
+ s.add_development_dependency "redcarpet"
31
+ s.add_development_dependency "rspec"
32
+ s.add_development_dependency "rspec_junit"
33
+ s.add_development_dependency "rspec_junit_formatter"
34
+ s.add_development_dependency "rubocop"
35
+ s.add_development_dependency "simplecov"
36
+ s.add_development_dependency "spring"
37
+ s.add_development_dependency "terminal-notifier-guard" if /Darwin/.match?(`uname -a`.strip)
38
+ s.add_development_dependency "yard"
39
+ end
@@ -3,126 +3,174 @@
3
3
  # See README.me for the descriptions.
4
4
 
5
5
  module BlankEmptyNilFilters
6
+ # These filter methods are used on both the Array and Hash extensions
7
+ module FilterMethods
8
+ def maybe_recurse(val, scanner, condition, start, depth, level)
9
+ if level >= start && (depth.nil? || level < depth)
10
+ if val.respond_to?(scanner)
11
+ val.send(scanner, condition, start, depth, level+1) # recurse
12
+ else
13
+ val
14
+ end
15
+ else
16
+ val
17
+ end
18
+ end
19
+
20
+ def maybe_apply(val, condition, start, depth, level)
21
+ val.send(condition) if level >= start && (depth.nil? || level < depth)
22
+ end
23
+ end
24
+
6
25
  module ArrayExtensions
7
- def no_empty_values
8
- reject_values(:is_empty?)
26
+ def no_empty_values(start = 0, depth = nil, level = 0)
27
+ reject_values(:is_empty?, start, depth, level)
9
28
  end
10
29
  alias reject_empty_values no_empty_values
11
30
 
12
- def no_blank_values
13
- reject_values(:is_blank?)
31
+ def no_blank_values(start = 0, depth = nil, level = 0)
32
+ reject_values(:is_blank?, start, depth, level)
14
33
  end
15
34
  alias reject_blank_values no_blank_values
16
35
 
17
- def no_nil_values
18
- reject_values(:nil?)
36
+ def no_nil_values(start = 0, depth = nil, level = 0)
37
+ reject_values(:nil?, start, depth, level)
19
38
  end
20
39
  alias reject_nil_values no_nil_values
21
40
 
22
- def only_empty_values
23
- select_values(:is_empty?)
41
+ def only_empty_values(start = 0, depth = nil, level = 0)
42
+ select_values(:is_empty?, start, depth, level)
24
43
  end
44
+ alias select_empty_values only_empty_values
25
45
 
26
- def only_blank_values
27
- select_values(:is_blank?)
46
+ def only_blank_values(start = 0, depth = nil, level = 0)
47
+ select_values(:is_blank?, start, depth, level)
28
48
  end
49
+ alias select_blank_values only_blank_values
29
50
 
30
- def only_nil_values
31
- select_values(:is_nil?)
51
+ def only_nil_values(start = 0, depth = nil, level = 0)
52
+ select_values(:is_nil?, start, depth, level)
32
53
  end
54
+ alias select_nil_values only_nil_values
33
55
 
34
- def is_empty?
35
- length.zero? || reject_empty_values.length.zero?
56
+ def is_empty?(start = 0, depth = nil, level = 0)
57
+ length.zero? || no_empty_values(start, depth, level).length.zero?
36
58
  end
37
59
 
38
- def is_blank?
39
- is_empty? || reject_blank_values.length.zero?
60
+ def is_blank?(start = 0, depth = nil, level = 0)
61
+ is_empty? || no_blank_values(start, depth, level).length.zero?
40
62
  end
41
63
 
42
- def reject_values(filter)
43
- map { |val| val.respond_to?(:reject_values) ? val.reject_values(filter) : val }
44
- .reject { |val| val.send(filter) }
64
+ # @param [Symbol] condition the name of the filter method (eg: :is_empty?)
65
+ # @param [Integer] start the starting level at which filtering occurs; default: 0
66
+ # @param [Integer|nil] depth the maximum level at which filtering occurs; defaults to nil for no limit
67
+ # @param [Integer] level the current level; defaults to 0
68
+ # @return [Array] the filtered array after having recursively applied +condition+ to each
69
+ # element and removing those for which the condition is true
70
+ def reject_values(condition, start = 0, depth = nil, level = 0)
71
+ filter_values(:reject_values, :reject, condition, start, depth, level)
45
72
  end
46
73
  alias no_values reject_values
47
74
 
48
- def select_values(filter)
49
- map { |val| val.respond_to?(:select_values) ? val.select_values(filter) : val }
50
- .select { |val| val.send(filter) }
75
+ # @param [Symbol] condition the name of the filter method (eg: :is_empty?)
76
+ # @param [Integer] start the starting level at which filtering occurs; default: 0
77
+ # @param [Integer|nil] depth the maximum level at which filtering occurs; nil = no limit
78
+ # @param [Integer] level the current level; defaults to 0
79
+ # @return [Array] the filtered array after having recursively applied +condition+ to each element
80
+ # element and selecting out those for which the condition is true
81
+ def select_values(condition, start = 0, depth = nil, level = 0)
82
+ filter_values(:select_values, :select, condition, start, depth, level)
51
83
  end
52
84
  alias only_values select_values
85
+
86
+ private
87
+
88
+ include FilterMethods
89
+
90
+ def filter_values(scanner, selector, condition, start, depth, level)
91
+ map { |val| maybe_recurse(val, scanner, condition, start, depth, level) }
92
+ .send(selector) { |val| maybe_apply(val, condition, start, depth, level) }
93
+ end
53
94
  end
54
95
 
55
96
  module HashExtensions
56
- def no_empty_values
57
- reject_values(:is_empty?)
97
+ def no_empty_values(start = 0, depth = nil, level = 0)
98
+ reject_values(:is_empty?, start, depth, level)
58
99
  end
59
100
  alias reject_empty_values no_empty_values
60
101
 
61
- def only_empty_values
62
- select_values(:is_empty?)
102
+ def only_empty_values(start = 0, depth = nil, level = 0)
103
+ select_values(:is_empty?, start, depth, level)
63
104
  end
64
105
  alias select_empty_values only_empty_values
65
106
 
66
- def no_blank_values
67
- reject_values(:is_blank?)
107
+ def no_blank_values(start = 0, depth = nil, level = 0)
108
+ reject_values(:is_blank?, start, depth, level)
68
109
  end
69
110
  alias reject_blank_values no_blank_values
70
111
 
71
- def only_blank_values
72
- select_values(:is_blank?)
112
+ def only_blank_values(start = 0, depth = nil, level = 0)
113
+ select_values(:is_blank?, start, depth, level)
73
114
  end
74
115
  alias select_blank_values only_blank_values
75
116
 
76
- def no_nil_values
77
- reject_values(:nil?)
117
+ def no_nil_values(start = 0, depth = nil, level = 0)
118
+ reject_values(:nil?, start, depth, level)
78
119
  end
79
120
  alias reject_nil_values no_nil_values
80
121
 
81
- def only_nil_values
82
- select_values(:nil?)
122
+ def only_nil_values(start = 0, depth = nil, level = 0)
123
+ select_values(:nil?, start, depth, level)
83
124
  end
84
125
  alias select_nil_values only_nil_values
85
126
 
86
- def empty_value_keys
87
- only_empty_values.keys
127
+ def empty_value_keys(start = 0, depth = nil, level = 0)
128
+ only_empty_values(start, depth, level).keys
88
129
  end
89
130
 
90
- def blank_value_keys
91
- only_blank_values.key
131
+ def blank_value_keys(start = 0, depth = nil, level = 0)
132
+ only_blank_values(start, depth, level).keys
92
133
  end
93
134
 
94
- def nil_value_keys
95
- only_nil_values.keys
135
+ def nil_value_keys(start = 0, depth = nil, level = 0)
136
+ only_nil_values(start, depth, level).keys
96
137
  end
97
138
 
98
- def non_empty_value_keys
99
- no_empty_values.key
139
+ def non_empty_value_keys(start = 0, depth = nil, level = 0)
140
+ no_empty_values(start, depth, level).keys
100
141
  end
101
142
 
102
- def non_blank_value_keys
103
- no_blank_values.keys
143
+ def non_blank_value_keys(start = 0, depth = nil, level = 0)
144
+ no_blank_values(start, depth, level).keys
104
145
  end
105
146
 
106
- def non_nil_value_keys
107
- no_nil_values.keys
147
+ def non_nil_value_keys(start = 0, depth = nil, level = 0)
148
+ no_nil_values(start, depth, level).keys
108
149
  end
109
150
 
110
- def is_empty?
111
- length.zero? || no_empty_values.length.zero?
151
+ def is_empty?(start = 0, depth = nil, level = 0)
152
+ length.zero? || no_empty_values(start, depth, level).length.zero?
112
153
  end
113
154
 
114
- def is_blank?
115
- length.zero? || reject_blank_values.length.zero?
155
+ def is_blank?(start = 0, depth = nil, level = 0)
156
+ length.zero? || reject_blank_values(start, depth, level).length.zero?
157
+ end
158
+
159
+ def reject_values(condition, start = 0, depth = nil, level = 0)
160
+ filter_hash_values(:reject_values, :reject, condition, start, depth, level)
116
161
  end
117
162
 
118
- def reject_values(filter)
119
- dup.transform_values { |val| val.respond_to?(:reject_values) ? val.reject_values(filter) : val }
120
- .reject { |_key, val| val.send(filter) }
163
+ def select_values(condition, start = 0, depth = nil, level = 0)
164
+ filter_hash_values(:select_values, :select, condition, start, depth, level)
121
165
  end
122
166
 
123
- def select_values(filter)
124
- dup.transform_values { |val| val.respond_to?(:select_values) ? val.select_values(filter) : val }
125
- .select { |_key, val| val.send(filter) }
167
+ private
168
+
169
+ include FilterMethods
170
+
171
+ def filter_hash_values(scanner, selector, condition, start, depth, level)
172
+ dup.transform_values { |val| maybe_recurse(val, scanner, condition, start, depth, level) }
173
+ .send(selector) { |_key, val| maybe_apply(val, condition, start, depth, level) }
126
174
  end
127
175
  end
128
176
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BlankEmptyNilFilters
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blank_empty_nil_filters
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alan Stebbens
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-23 00:00:00.000000000 Z
11
+ date: 2020-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -249,6 +249,7 @@ files:
249
249
  - LICENSE.md
250
250
  - README.md
251
251
  - Rakefile
252
+ - blank_empty_nil_filters.gemspec
252
253
  - lib/blank_empty_nil_filters.rb
253
254
  - lib/blank_empty_nil_filters/version.rb
254
255
  homepage: https://github.com/aks/blank_empty_nil_filters
@@ -270,8 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
271
  - !ruby/object:Gem::Version
271
272
  version: '0'
272
273
  requirements: []
273
- rubyforge_project:
274
- rubygems_version: 2.6.14
274
+ rubygems_version: 3.1.2
275
275
  signing_key:
276
276
  specification_version: 4
277
277
  summary: '["Extensions for filtering empty, blank, and nil values from Hashes and