philter 0.4.0 → 0.6.0

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