philter 0.4.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1245b87b0b4e2ca1f90789b959f544411aaa7202
4
- data.tar.gz: df95daab4acadb6fb075b7d21b8618c0f281ab76
3
+ metadata.gz: d34fdc2c11fc99bd8a888a5fbc35f53c6ffd21cf
4
+ data.tar.gz: 01a3d93900d8c15305ca92e31a35937c91e307ff
5
5
  SHA512:
6
- metadata.gz: ab0e2ffe2422d1babca9c368d33b076eefc7b27d33ac94c76a71917a13edd68737bbd2d4c8850c34bde622f96883e2ff7bdb123b11cc7b60aa9c77978fdbcdb6
7
- data.tar.gz: 3e0cfffe99f31f60fc7456e3dd81b9344f65c3b1a07b354d4df00726d908c241f3f61d2554bcdd8cfbf4d6da743cc7490f53bd7caf696a0a151f9d04438914db
6
+ metadata.gz: 68143b50dacb7215269c26253418c3e6dacf266fd6290377f30770872042cfeae91cf794ec3d8347c845359b08ecea803f0e12c1220d141a0a0258f565fa9a72
7
+ data.tar.gz: 9be1d27635d66c6e2a533704629895ef25c253102b0ced666dfb8b7275a2576b169635d09fca77fa49de8abea19cd89433323a7ab57aa1146676ebbd480ad942
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ v0.6.0 [☰](https://github.com/marcomd/Philter/compare/v0.5.0...v0.6.0) May 24th, 2016
2
+ ------------------------------
3
+ * Improved code readability
4
+ * Improved documentation
5
+
6
+ v0.5.0 [☰](https://github.com/marcomd/Philter/compare/v0.4.0...v0.5.0) May 24th, 2016
7
+ ------------------------------
8
+ * Improved code readability
9
+ * Improved documentation with benchmarks
10
+
1
11
  v0.4.0 [☰](https://github.com/marcomd/Philter/compare/v0.3.0...v0.4.0) May 23th, 2016
2
12
  ------------------------------
3
13
  * Improved code quality
data/README.md CHANGED
@@ -6,7 +6,10 @@
6
6
  [![Travis CI ](http://img.shields.io/travis/marcomd/Philter/master.svg) ](https://travis-ci.org/marcomd/Philter)
7
7
  [![Quality ](http://img.shields.io/codeclimate/github/marcomd/Philter.svg)](https://codeclimate.com/github/marcomd/Philter)
8
8
 
9
- This gem let you to filter any kind of arrays to get the item or attributes of selected items
9
+ This gem let you to filter any kind of arrays to get the item or attributes of selected items.
10
+ It's short and dynamic which helps to increase the readability.
11
+ Its trace is a usefull tool for teachers.
12
+ Performance it's not its field, see the section below.
10
13
 
11
14
 
12
15
  ![](/assets/logo.png)
@@ -21,6 +24,12 @@ require 'philter'
21
24
  [1,2,3].philter [2,3]
22
25
  => [2,3]
23
26
 
27
+ [1,2,3].philter '<= 2'
28
+ => [1,2]
29
+
30
+ [1,2,3].philter '!= 2'
31
+ => [1,3]
32
+
24
33
  %w[red green blue].philter 'red'
25
34
  => ["red"]
26
35
 
@@ -63,14 +72,17 @@ require 'philter'
63
72
  {id: 3, name: 'Bill', email: 'bill@live.com' }
64
73
  ].philter({email: /@gmail/}, get: :name)
65
74
  => ["Mark", "Larry"]
75
+ ```
66
76
 
67
- # Debug mode
77
+ Get the trace with the option `debug: true`
78
+
79
+ ```ruby
68
80
  [
69
81
  {id: 1, name: 'Mark' },
70
82
  {id: 2, name: 'Larry' },
71
83
  {id: 3, name: 'Bill' }
72
84
  ].philter({id: [1,3]}, debug: true)
73
-
85
+ # You will get a trace
74
86
  item Hash {:id=>1, :name=>"Mark"}
75
87
  a. search: Array [:id, [1, 3]]
76
88
  1.y label: Symbol .2 Hash[:id] == value | 1 == 1 => X
@@ -107,6 +119,65 @@ cities.philter(region: /\Alomb/i).size
107
119
  => 4
108
120
  ```
109
121
 
122
+ ## Performance
123
+
124
+ If you need a lot of speed it would be better to use grep when you can or select manually your items.
125
+
126
+ ```ruby
127
+ require 'benchmark'
128
+
129
+ ar_test = 100.times.map{|n| n}
130
+ Benchmark.bmbm do |x|
131
+ x.report("philter: ") { 1_000.times { ar_test.philter [1,2] } }
132
+ x.report("grep: ") { 1_000.times { ar_test.grep [1,2] } }
133
+ end
134
+
135
+ Rehearsal ---------------------------------------------
136
+ philter: 1.872000 0.000000 1.872000 ( 1.859130)
137
+ grep: 0.031000 0.000000 0.031000 ( 0.017170)
138
+ ------------------------------------ total: 1.903000sec
139
+
140
+ user system total real
141
+ philter: 1.826000 0.000000 1.826000 ( 1.834825)
142
+ grep: 0.016000 0.000000 0.016000 ( 0.016777)
143
+ ```
144
+
145
+ ```ruby
146
+ Benchmark.bmbm do |x|
147
+ x.report("philter: ") { 1_000.times { ar_test.philter '< 50' } }
148
+ x.report("select: ") { 1_000.times { ar_test.select {|item| item < 50} } }
149
+ end
150
+
151
+ Rehearsal ---------------------------------------------
152
+ philter: 3.775000 0.000000 3.775000 ( 3.779718)
153
+ select: 0.000000 0.000000 0.000000 ( 0.004455)
154
+ ------------------------------------ total: 3.775000sec
155
+
156
+ user system total real
157
+ philter: 3.744000 0.000000 3.744000 ( 3.746851)
158
+ select: 0.016000 0.000000 0.016000 ( 0.004338)
159
+ ```
160
+
161
+ ```ruby
162
+ ar_test = [ {id: 1, name: 'Mark', email: 'mark@gmail.com'},
163
+ {id: 2, name: 'Bill', email: 'bill@live.com'},
164
+ {id: 3, name: 'Larry', email: 'larry@gmail.com'}]
165
+ regexp = /\A.+gmail/
166
+ Benchmark.bmbm do |x|
167
+ x.report("philter: ") { 10_000.times { ar_test.philter email: regexp } }
168
+ x.report("select: ") { 10_000.times { ar_test.select {|item| item[:email] =~ regexp} } }
169
+ end
170
+
171
+ Rehearsal ---------------------------------------------
172
+ philter: 0.515000 0.000000 0.515000 ( 0.490562)
173
+ select: 0.000000 0.000000 0.000000 ( 0.003961)
174
+ ------------------------------------ total: 0.515000sec
175
+
176
+ user system total real
177
+ philter: 0.468000 0.000000 0.468000 ( 0.473782)
178
+ select: 0.000000 0.000000 0.000000 ( 0.003429)
179
+ ```
180
+
110
181
  ## Compatibility
111
182
 
112
183
  Ruby `1.9+`
@@ -117,6 +188,11 @@ Ruby `1.9+`
117
188
 
118
189
  To use it in a rails project, add to gem file `gem 'philter'` and run `bundle install`
119
190
 
191
+ ## To Do
192
+
193
+ * Add boolean operator to chain of conditions
194
+ * Improve performance keeping the operations's trace
195
+
120
196
  ## Contributing
121
197
 
122
198
  1. Fork it
data/lib/array.rb CHANGED
@@ -6,95 +6,43 @@ class Array
6
6
  debug: false
7
7
  }.merge(options)
8
8
  unless search
9
- puts philter_help if options[:debug]
10
- raise "Specify search parameter!"
9
+ puts philter_help if options[:debug]
10
+ raise "Specify search parameter!"
11
11
  end
12
12
  results = []
13
13
  self.each do |item|
14
- puts "item #{item.class.name} #{item}" if options[:debug]
15
- h_selected = {all: nil, at_least_one: nil}
16
- if search.respond_to? :each
17
- # search: {} or []
18
- search.each do |value|
19
- # Every item must match with search options to be selected
20
- puts " a. search: #{value.class.name} #{value}" if options[:debug]
21
- if value.is_a?(Array)
22
- # Example search: {code: 1} or search: {code: [1,2]}
23
- label, values = value
24
- values = [values] unless values.is_a?(Array)
25
- values.each do |value|
26
- selected = nil
27
- if item.respond_to?(label)
28
- print " 1.x " if options[:debug]
29
- if value.is_a?(Regexp)
30
- print " .1 " if options[:debug]
31
- selected = phil_evaluate item, label, value, :method, options.merge(operator: '=~')
32
- else
33
- # search: {id: 2}
34
- # search: {id: '<3'} or any other operator
35
- print " .2 " if options[:debug]
36
- selected = phil_evaluate item, label, value, :method, options.merge(operator: '==')
37
- end
38
- elsif item.respond_to? '[]'
39
- print " 1.y label: #{label.class.name}" if options[:debug]
40
- if value.is_a?(Regexp)
41
- # search: {email: /@gmail/}
42
- print " .1 " if options[:debug]
43
- selected = phil_evaluate item, label, value, :hash, options.merge(operator: '=~')
44
- elsif item.is_a?(Hash) && !label.is_a?(Fixnum)
45
- # search: {id: 1} or {'name' => 'Mark'}
46
- # search: {id: '<3'} or any other operator
47
- print " .2 " if options[:debug]
48
- selected = phil_evaluate item, label, value, :hash, options.merge(operator: '==')
49
- else
50
- print " .3 no action for #{value} !!!" if options[:debug]
51
- end
52
- else
53
- print " 1.z selector not present !!!" if options[:debug]
54
- end
55
- puts " #{'=> X' if selected}" if options[:debug]
56
- h_selected[:at_least_one] ||= selected
57
- end
58
- elsif value.is_a?(Regexp)
59
- # search: {email: /@gmail/}
60
- print " 2. " if options[:debug]
61
- selected = phil_evaluate item, nil, value, :simple, options.merge(operator: '=~')
62
- puts " #{'=> X' if selected}" if options[:debug]
63
- h_selected[:at_least_one] ||= selected
64
- else
65
- # Example search: [3] or search: [3, 4]
66
- print " 3. " if options[:debug]
67
- selected = phil_evaluate item, nil, value, :simple, options.merge(operator: '==')
68
- puts " #{'=> X' if selected}" if options[:debug]
69
- h_selected[:at_least_one] ||= selected
70
- end
71
- end
72
- elsif search.is_a?(Regexp)
73
- # Search has one item
74
- # search: 3 or search: 'a'
75
- print " b. " if options[:debug]
76
- selected = phil_evaluate item, nil, search, :simple, options.merge(operator: '=~')
77
- puts " #{'=> X' if selected}" if options[:debug]
78
- h_selected[:at_least_one] ||= selected
79
- else
80
- # Search has one item
81
- # search: 3 or search: 'a'
82
- # search: '<3' or any other operator
83
- print " c. " if options[:debug]
84
- selected = phil_evaluate item, nil, search, :simple, options.merge(operator: '==')
85
- puts " #{'=> X' if selected}" if options[:debug]
86
- h_selected[:at_least_one] ||= selected
87
- end
88
- if h_selected[:at_least_one] || h_selected[:all]
89
- tmp_result = if options[:get]
90
- item.respond_to?(options[:get]) ? item.send(options[:get]) : item[options[:get]]
91
- else
92
- item
93
- end
94
- results << tmp_result
14
+ puts "item #{item.class.name} #{item}" if options[:debug]
15
+ if search.respond_to? :each
16
+ # search: {} or []
17
+ selected = phil_search_from_list search, item, options
18
+ elsif search.is_a?(Regexp)
19
+ # Search has one item
20
+ # search: 3 or search: 'a'
21
+ print " b. " if options[:debug]
22
+ selected = phil_evaluate item, nil, search, :simple, options.merge(operator: '=~')
23
+ puts " #{'=> X' if selected}" if options[:debug]
24
+ else
25
+ # Search has one item
26
+ # search: 3 or search: 'a'
27
+ # search: '<3' or any other operator
28
+ print " c. " if options[:debug]
29
+ selected = phil_evaluate item, nil, search, :simple, options.merge(operator: '==')
30
+ puts " #{'=> X' if selected}" if options[:debug]
31
+ end
32
+ if selected
33
+ results <<
34
+ if options[:get]
35
+ if item.respond_to? options[:get]
36
+ item.send options[:get]
37
+ elsif item.respond_to? '[]'
38
+ item[options[:get]]
39
+ end
40
+ else
41
+ item
95
42
  end
43
+ end
96
44
  end
97
- puts "------------------" if options[:debug]
45
+ puts "------------------" if options[:debug]
98
46
  puts " #{results ? results.size : 'No'} item#{results && results.size == 1 ? '' : 's'} found" if options[:debug]
99
47
  results
100
48
  end
data/lib/base.rb CHANGED
@@ -46,16 +46,82 @@ module Philter
46
46
  print "| #{item.send(label)} #{operator} #{value}" if options[:debug]
47
47
  eval("item.send(label) #{operator} value")
48
48
  when :hash
49
- print " #{item.class.name}[:#{label}] #{operator} value" if options[:debug]
50
- print "| #{item[label]} #{operator} #{value} " if options[:debug]
49
+ print " #{item.class.name}[:#{label}] #{operator} value" if options[:debug]
50
+ print "| #{item[label]} #{operator} #{value} " if options[:debug]
51
51
  eval("item[label]#{item_to_s} #{operator} value")
52
52
  when :simple
53
53
  print " item #{operator} value" if options[:debug]
54
- print " | #{item} #{operator} #{value}" if options[:debug]
54
+ print " | #{item} #{operator} #{value}" if options[:debug]
55
55
  eval("item#{item_to_s} #{operator} value")
56
56
  else
57
57
  raise "phil_evaluate: evaluation #{evaluation ? "#{evaluation} not valid!" : "blank!"}"
58
58
  end
59
59
  end
60
+
61
+ # Search params respond to each method
62
+ def phil_search_from_list search, item, options={}
63
+ selected_or, selected_and = nil, nil
64
+ search.each do |value|
65
+ # Every item must match with search options to be selected
66
+ puts " a. search: #{value.class.name} #{value}" if options[:debug]
67
+ if value.is_a?(Array)
68
+ # Example search: {code: 1} or search: {code: [1,2]}
69
+ label, values = value
70
+ values = [values] unless values.is_a?(Array)
71
+ values.each do |value|
72
+ selected = phil_search_is_array label, value, item, options
73
+ selected_or = true if !selected_or && selected
74
+ selected_and = selected if selected_and
75
+ end
76
+ elsif value.is_a?(Regexp)
77
+ # search: {email: /@gmail/}
78
+ print " 2. " if options[:debug]
79
+ selected = phil_evaluate item, nil, value, :simple, options.merge(operator: '=~')
80
+ puts " #{'=> X' if selected}" if options[:debug]
81
+ else
82
+ # Example search: [3] or search: [3, 4]
83
+ print " 3. " if options[:debug]
84
+ selected = phil_evaluate item, nil, value, :simple, options.merge(operator: '==')
85
+ puts " #{'=> X' if selected}" if options[:debug]
86
+ end
87
+ selected_or = true if !selected_or && selected
88
+ selected_and = selected if selected_and
89
+ end
90
+ selected_or
91
+ end
92
+
93
+ def phil_search_is_array label, value, item, options={}
94
+ selected = nil
95
+ if item.respond_to?(label)
96
+ print " 1.x " if options[:debug]
97
+ if value.is_a?(Regexp)
98
+ print " .1 " if options[:debug]
99
+ selected = phil_evaluate item, label, value, :method, options.merge(operator: '=~')
100
+ else
101
+ # search: {id: 2}
102
+ # search: {id: '<3'} or any other operator
103
+ print " .2 " if options[:debug]
104
+ selected = phil_evaluate item, label, value, :method, options.merge(operator: '==')
105
+ end
106
+ elsif item.respond_to? '[]'
107
+ print " 1.y label: #{label.class.name}" if options[:debug]
108
+ if value.is_a?(Regexp)
109
+ # search: {email: /@gmail/}
110
+ print " .1 " if options[:debug]
111
+ selected = phil_evaluate item, label, value, :hash, options.merge(operator: '=~')
112
+ elsif item.is_a?(Hash) && !label.is_a?(Fixnum)
113
+ # search: {id: 1} or {'name' => 'Mark'}
114
+ # search: {id: '<3'} or any other operator
115
+ print " .2 " if options[:debug]
116
+ selected = phil_evaluate item, label, value, :hash, options.merge(operator: '==')
117
+ else
118
+ print " .3 no action for #{value} !!!" if options[:debug]
119
+ end
120
+ else
121
+ print " 1.z selector not present !!!" if options[:debug]
122
+ end
123
+ puts " #{'=> X' if selected}" if options[:debug]
124
+ selected
125
+ end
60
126
  end
61
127
  end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Philter
2
2
  def self.version
3
- "0.4.0"
3
+ "0.6.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Mastrodonato