iteraptor 0.4.0 → 0.5.0
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 +4 -4
- data/Gemfile +0 -1
- data/README.md +4 -1
- data/iteraptor.gemspec +4 -3
- data/lib/iteraptor/version.rb +1 -1
- data/lib/iteraptor.rb +107 -41
- metadata +24 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98397269de93f3ef4ade2c6910e602576ce96b10
|
4
|
+
data.tar.gz: c530c00a774a1f251aa7024d19861661a43ba4b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ead6d1ff57914ff11d3607ff0b31e580e7fdeaa0352aa1e4427c17e46a1997e90f1885a6576a7d85858e1dd21da945befa81d3aa827129a109b4cc8b5a8e8c0f
|
7
|
+
data.tar.gz: 31f7e4a9d26fabee622e5a9a997f1b7e1cad9e9df3a0a9a603b08cabf0cd3ce324b8da131706b548cee55383b15461e2320f23814decd51f1145ba63ca20f540
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -38,8 +38,11 @@ element;
|
|
38
38
|
whatever it is; `nil`s are not treated in some special way
|
39
39
|
* `aplanar` (_sp._ `flatten`) the analogue of `Array#flatten`, but flattens
|
40
40
|
the deep enumerable into `Hash` instance
|
41
|
+
* `recoger` (_sp._ `harvest`, `collect`) the opposite to `aplanar`, it builds
|
42
|
+
the nested structure out of flattened hash
|
41
43
|
* `segar` (_sp._ `yield`), alias `escoger` (_sp._ `select`) allows to filter
|
42
|
-
and collect elelements
|
44
|
+
and collect elelements
|
45
|
+
* `rechazar` (_sp._ `reject`) allows to filter out and collect elelements.
|
43
46
|
|
44
47
|
### Iteration
|
45
48
|
|
data/iteraptor.gemspec
CHANGED
@@ -25,7 +25,8 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.require_paths = ['lib']
|
26
26
|
|
27
27
|
spec.add_development_dependency 'bundler', '~> 1'
|
28
|
-
spec.add_development_dependency 'rake', '~> 10
|
29
|
-
spec.add_development_dependency 'rspec', '~> 3
|
30
|
-
spec.add_development_dependency 'pry'
|
28
|
+
spec.add_development_dependency 'rake', '~> 10'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3'
|
30
|
+
spec.add_development_dependency 'pry'
|
31
|
+
spec .add_development_dependency 'awesome_print'
|
31
32
|
end
|
data/lib/iteraptor/version.rb
CHANGED
data/lib/iteraptor.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require "iteraptor/version"
|
2
2
|
|
3
|
+
# rubocop:disable Style/VariableNumber
|
4
|
+
# rubocop:disable Metrics/ModuleLength
|
3
5
|
module Iteraptor
|
4
6
|
DELIMITER = '.'.freeze
|
5
7
|
|
@@ -8,58 +10,65 @@ module Iteraptor
|
|
8
10
|
end
|
9
11
|
|
10
12
|
%i[cada mapa].each do |m|
|
11
|
-
define_method m do |root = nil, parent = nil, &λ|
|
12
|
-
return enum_for(m, root, parent) unless λ
|
13
|
+
define_method m do |root = nil, parent = nil, **params, &λ|
|
14
|
+
return enum_for(m, root, parent, **params) unless λ
|
15
|
+
return self if empty?
|
16
|
+
|
13
17
|
send_to = [Hash, Array, Enumerable].detect(&method(:is_a?))
|
14
|
-
send_to && send("#{m}_in_#{send_to.name.downcase}", root || self, parent, &λ)
|
18
|
+
send_to && send("#{m}_in_#{send_to.name.downcase}", root || self, parent, **params, &λ)
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def segar filter
|
22
|
-
return enum_for(:segar, filter) unless block_given?
|
23
|
-
|
24
|
-
cada.with_object({}) do |(parent, element), memo|
|
25
|
-
p = parent.split(DELIMITER)
|
26
|
-
if case filter
|
27
|
-
when String then p.include?(filter)
|
28
|
-
when Symbol then p.include?(filter.to_s)
|
29
|
-
when Regexp then p.any? { |key| key =~ filter }
|
30
|
-
when Array then parent.include?(filter.map(&:to_s).join(DELIMITER))
|
31
|
-
end
|
32
|
-
yield parent, element
|
33
|
-
memo[parent] = element
|
34
|
-
end
|
35
|
-
end
|
22
|
+
def rechazar *filter, **params
|
23
|
+
return self if empty?
|
24
|
+
rechazar_o_escoger false, *filter, **params
|
36
25
|
end
|
37
26
|
|
38
|
-
def
|
27
|
+
def escoger *filter, **params
|
28
|
+
return self if empty?
|
29
|
+
rechazar_o_escoger true, *filter, **params
|
30
|
+
end
|
31
|
+
|
32
|
+
# rubocop:disable Style/Alias
|
33
|
+
alias_method :segar, :escoger
|
34
|
+
# rubocop:enable Style/Alias
|
35
|
+
|
36
|
+
def aplanar delimiter: DELIMITER, **params
|
37
|
+
return self if empty?
|
39
38
|
cada.with_object({}) do |(parent, element), acc|
|
40
39
|
key = parent.tr(DELIMITER, delimiter)
|
41
|
-
key = key.to_sym if symbolize_keys
|
40
|
+
key = key.to_sym if params[:symbolize_keys]
|
42
41
|
acc[key] = element unless element.is_a?(Enumerable)
|
43
42
|
yield key, element if block_given?
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
47
|
-
def
|
48
|
-
return
|
49
|
-
|
50
|
-
|
46
|
+
def recoger delimiter: DELIMITER, **params
|
47
|
+
return self if empty?
|
48
|
+
# rubocop:disable Style/MultilineBlockChain
|
49
|
+
aplanar.each_with_object(
|
50
|
+
Hash.new { |h, k| h[k] = h.clone.clear }
|
51
|
+
) do |(k, v), acc|
|
52
|
+
keys = k.split(delimiter)
|
53
|
+
parent = keys[0..-2].reduce(acc){ |h, kk| h[kk] }
|
54
|
+
parent[keys.last] = v
|
55
|
+
end.mapa(yield_all: true, **params) do |_parent, (k, v)|
|
56
|
+
[k, v]
|
57
|
+
end
|
58
|
+
# rubocop:enable Style/MultilineBlockChain
|
59
|
+
end
|
60
|
+
|
61
|
+
def plana_mapa delimiter: DELIMITER, **params
|
62
|
+
return enum_for(:plana_mapa, delimiter: delimiter, **params) unless block_given?
|
63
|
+
return self if empty?
|
51
64
|
|
52
65
|
cada.with_object([]) do |(parent, element), acc|
|
53
66
|
key = parent.tr(DELIMITER, delimiter)
|
54
|
-
key = key.to_sym if symbolize_keys
|
67
|
+
key = key.to_sym if params[:symbolize_keys]
|
55
68
|
acc << yield(key, element) unless element.is_a?(Enumerable)
|
56
69
|
end
|
57
70
|
end
|
58
71
|
|
59
|
-
# rubocop:enable Metrics/MethodLength
|
60
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
61
|
-
# rubocop:enable Style/MultilineIfModifier
|
62
|
-
|
63
72
|
private
|
64
73
|
|
65
74
|
##############################################################################
|
@@ -71,7 +80,7 @@ module Iteraptor
|
|
71
80
|
end
|
72
81
|
end
|
73
82
|
|
74
|
-
def cada_in_array root = nil, parent = nil
|
83
|
+
def cada_in_array root = nil, parent = nil, **_
|
75
84
|
λ = Proc.new
|
76
85
|
each.with_index do |e, idx|
|
77
86
|
[parent, idx].compact.join(DELIMITER).tap do |p|
|
@@ -82,7 +91,7 @@ module Iteraptor
|
|
82
91
|
end
|
83
92
|
alias cada_in_enumerable cada_in_array
|
84
93
|
|
85
|
-
def cada_in_hash root = nil, parent = nil
|
94
|
+
def cada_in_hash root = nil, parent = nil, **_
|
86
95
|
λ = Proc.new
|
87
96
|
each do |k, v|
|
88
97
|
[parent, k].compact.join(DELIMITER).tap do |p|
|
@@ -94,33 +103,90 @@ module Iteraptor
|
|
94
103
|
|
95
104
|
##############################################################################
|
96
105
|
### mapa
|
97
|
-
|
106
|
+
# FIXME what happens if I return nil from mapa in array?
|
107
|
+
# Params:
|
108
|
+
# - with_index
|
109
|
+
# - yield_all
|
110
|
+
# - symbolize_keys
|
111
|
+
def mapa_in_array root = nil, parent = nil, **params
|
98
112
|
λ = Proc.new
|
99
113
|
|
100
114
|
map.with_index do |e, idx|
|
101
115
|
p = [parent, idx].compact.join(DELIMITER)
|
102
116
|
|
117
|
+
e = yield p, (params[:with_index] ? [idx.to_s, e] : e) if !e.is_a?(Enumerable) || params[:yield_all]
|
118
|
+
|
103
119
|
case e
|
104
|
-
when Iteraptor then e.mapa(root, p, &λ)
|
120
|
+
when Iteraptor then e.mapa(root, p, **params, &λ)
|
105
121
|
when Enumerable then e.map(&λ.curry[p])
|
106
|
-
else
|
122
|
+
else e
|
107
123
|
end
|
108
124
|
end
|
109
125
|
end
|
110
126
|
alias mapa_in_enumerable mapa_in_array
|
111
127
|
|
112
|
-
|
128
|
+
# Params:
|
129
|
+
# - yield_all
|
130
|
+
# - symbolize_keys
|
131
|
+
def mapa_in_hash root = nil, parent = nil, **params
|
113
132
|
λ = Proc.new
|
114
133
|
|
115
134
|
map do |k, v|
|
116
135
|
p = [parent, k].compact.join(DELIMITER)
|
117
136
|
|
137
|
+
k, v = yield p, [k, v] if !v.is_a?(Enumerable) || params[:yield_all]
|
138
|
+
|
118
139
|
case v
|
119
|
-
when Iteraptor then [k, v.mapa(root, p, &λ)]
|
140
|
+
when Iteraptor then [k, v.mapa(root, p, **params, &λ)]
|
120
141
|
when Enumerable then [k, v.map(&λ.curry[p])]
|
121
|
-
else
|
142
|
+
else k.nil? ? nil : [k, v]
|
122
143
|
end
|
123
|
-
end.compact.
|
144
|
+
end.compact.send(:to_hash_or_array, **params)
|
145
|
+
end
|
146
|
+
|
147
|
+
##############################################################################
|
148
|
+
### helpers
|
149
|
+
def safe_symbolize key
|
150
|
+
key.respond_to?(:to_sym) ? key.to_sym : key
|
151
|
+
end
|
152
|
+
|
153
|
+
def to_hash_or_array **params
|
154
|
+
# rubocop:disable Style/MultilineTernaryOperator
|
155
|
+
# rubocop:disable Style/RescueModifier
|
156
|
+
receiver =
|
157
|
+
is_a?(Array) &&
|
158
|
+
all? { |e| e.is_a?(Enumerable) && e.size == 2 } &&
|
159
|
+
map(&:first).uniq.size == size ? (to_h rescue self) : self
|
160
|
+
# rubocop:enable Style/RescueModifier
|
161
|
+
|
162
|
+
return receiver unless receiver.is_a?(Hash)
|
163
|
+
return receiver.values if receiver.keys.each_with_index.all? { |key, idx| key == idx.to_s }
|
164
|
+
return receiver unless params[:symbolize_keys]
|
165
|
+
|
166
|
+
receiver.map { |k, v| [safe_symbolize(k), v] }.to_h
|
167
|
+
# rubocop:enable Style/MultilineTernaryOperator
|
168
|
+
end
|
169
|
+
|
170
|
+
HASH_TO_ARRAY_ERROR_MSG = %(undefined method `hash_to_array?' for "%s":%s).freeze
|
171
|
+
def hash_to_hash_or_array
|
172
|
+
raise NoMethodError, HASH_TO_ARRAY_ERROR_MSG % [inspect, self.class] unless is_a?(Hash)
|
173
|
+
end
|
174
|
+
|
175
|
+
##############################################################################
|
176
|
+
# filters
|
177
|
+
def rechazar_o_escoger method, *filter, **params
|
178
|
+
raise ArgumentError, "no filter given in call to #{method ? :escoger : :rechazar}" if filter.empty?
|
179
|
+
|
180
|
+
plough = method ? :none? : :any?
|
181
|
+
aplanar.each_with_object({}) do |(key, value), acc|
|
182
|
+
to_match = key.split(DELIMITER)
|
183
|
+
to_match = to_match.flat_map { |k| [k.to_s, k.to_s.to_sym] } if params[:soft_keys]
|
184
|
+
|
185
|
+
next if filter.public_send(plough, &->(f){ to_match.any?(&f.method(:===)) })
|
186
|
+
|
187
|
+
value = yield key, value if block_given?
|
188
|
+
acc[key] = value
|
189
|
+
end.recoger(**params)
|
124
190
|
end
|
125
191
|
|
126
192
|
##############################################################################
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iteraptor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aleksei Matiushkin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -30,42 +30,56 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '10
|
33
|
+
version: '10'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '10
|
40
|
+
version: '10'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3
|
47
|
+
version: '3'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3
|
54
|
+
version: '3'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: pry
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: awesome_print
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0
|
82
|
+
version: '0'
|
69
83
|
description: Adds several methods similar to Enumerable’s iterators to where it is
|
70
84
|
included.
|
71
85
|
email:
|