blank_empty_nil_filters 0.1.1 → 0.1.2

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 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