filter 0.0.3 → 0.0.4

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.
@@ -1,22 +1,26 @@
1
1
  == Synopsys
2
- Enumerable#filter - extended Enumerable#select
2
+ <code>Enumerable#filter</code> - extended <code>Enumerable#select</code>
3
3
 
4
4
  == Examples
5
- String filter (acts like Enumerable#grep):
5
+ String filter (acts like <code>Enumerable#grep</code>):
6
6
  [1, 2, 3, 'ab'].filter(/a/) # => ['ab']
7
7
  [1, 2, 3, '3'].filter('3') # => ['3']
8
8
 
9
- You can pass a <tt>Proc</tt> or <tt>Symbol</tt>. Methods and blocks are allowed too:
9
+ You can pass a <code>Proc</code> or <code>Symbol</code>. Methods and blocks are allowed too:
10
10
  [1, 2, 3].filter(&:even?) # => [2]
11
11
  [1, 2, 3].filter(:even?) # => [2]
12
12
  [1, 2, 4].filter { |num| num.even? } # => [2, 4]
13
13
 
14
- <tt>Enumerable#filter</tt> can match against enumerable items attributes. Like this:
14
+ <code>Enumerable#filter</code> can match against enumerable items attributes. Like this:
15
15
  [1, 2, 3, 4.2].filter :to_i => :even? # => [2, 4]
16
16
 
17
- If the block is supplied, each matching element is passed to it, and the blocks result is stored in the output enumerator.
17
+ If the block is supplied, each matching element is passed to it, and the block's result is stored in the output array.
18
18
  [1, 2, 4].filter(&:even?) { |n| n + 1 } # => [3, 5]
19
19
 
20
- <tt>Enumerable#filter</tt> also accepts <tt>true</tt> or <tt>false</tt> as argument:
20
+ <code>Enumerable#filter</code> also accepts <code>true</code> or <code>false</code> as argument:
21
21
  [0, false, 2, nil].filter(true) # => [0, 2]
22
22
  [0, false, 2, nil].filter(false) # => [false, nil]
23
+
24
+ <code>Enumerable#filter</code> also supports <code>OR</code> operator!
25
+ Just pass many patterns, they will be joined together with <code>OR</code> operator.
26
+ [0, 2, 3, 4].filter(:zero?, :odd?) # => [0, 3]
@@ -1,8 +1,8 @@
1
- # == Synpsys
2
- # Extension for Ruby Enumerable module
1
+ # == Synopsys
2
+ # Extension for Ruby <code>Enumerable</code> module
3
3
  #
4
4
  # == Description
5
- # Extends Enumerable module with +filter+ method - enhanced version of Enumerable#select
5
+ # Extends <code>Enumerable</code> module with <code>filter</code> method - enhanced version of <code>Enumerable#select</code>.
6
6
  #
7
7
  # == Examples
8
8
  # [1, 2, 3, 'ab'].filter(/a/) # => ['ab']
@@ -11,50 +11,69 @@
11
11
  # [1, 2, 4].filter { |num| num.even? } # => [2, 4]
12
12
  # [1, 2, 4].filter(:even?) { |n| n + 1 } # => [3, 5]
13
13
  # [0, false, 2, nil].filter(true) # => [0, 2]
14
+ #
15
+ # <code>Enumerable#filter</code> also supports <code>OR</code> operator! Just pass many patterns as arguments.
16
+ # This snippet will match elements responding to <code>zero?</code> or <code>odd?</code> methods with <code>true</code>.
17
+ # [0, 2, 3, 4].filter(:zero?, :odd?) # => [0, 3]
14
18
  module Enumerable
15
19
  # Extended Enumerable#select combibed with Enumerable#collect
16
20
  #
17
- # When String or Regexp passed it acts as built-in +grep+ method, but return Enumerator instead of Array
18
- # Also you can pass Symbol, Proc or block
21
+ # When String or Regexp passed it acts as built-in <code>Enumerable#grep</code> method
22
+ # Also you can pass <code>Symbol, Proc, Method, Array, Hash, Class, Module, true, false, nil</code>.
23
+ # If the <code>block</code> is supplied without other arguments it will be used as filter.
24
+ # If the <code>block</code> is supplied with <code>patterns</code>,
25
+ # each matching element is passed to it, and the block's result is stored in the output array.
19
26
  #
20
- # @param pattern [Numeric|String|Regexp|Symbol|Proc|Method|NilClass|Hash|TrueClass|FalseClass|Module|Class]
27
+ # @param patterns *[Numeric|String|Regexp|Symbol|Proc|Method|NilClass|Hash|TrueClass|FalseClass|Module|Class]
21
28
  # @param block [Proc]
22
- def filter(pattern = nil, &block) # :yields: obj
23
- pattern, block = block, nil if block_given? && pattern.nil?
29
+ # @return [Enumerable]
30
+ def filter(*patterns, &block) # :yields: obj
31
+ # do nothing on null input
32
+ return self if !block_given? && patterns.empty?
33
+
34
+ # move +block+ to +patterns+ if no +patterns+ given
35
+ patterns, block = [block], nil if block_given? && patterns.empty?
36
+ conditions = patterns.map { |pattern| filter_condition(pattern) }
37
+
38
+ # match elements against all patterns using +OR+ operator
39
+ filtered = select do |obj|
40
+ conditions.any? { |condition| condition.call(obj) }
41
+ end
24
42
 
25
- filtered = case pattern
26
- when NilClass then self
43
+ # also transform elements if block given
44
+ block ? filtered.map(&block) : filtered
45
+ end
46
+
47
+ private
48
+ def filter_condition(pattern) #:nodoc:
49
+ # create filter condition from pattern
50
+ case pattern
51
+ when NilClass then proc { true }
27
52
 
28
53
  when Class, Module then
29
- select do |e|
54
+ proc do |e|
30
55
  e.is_a?(Class) || e.is_a?(Module) ?
31
56
  e <= pattern :
32
57
  e.is_a?(pattern)
33
58
  end
34
59
 
35
- when Symbol, Proc, Method then select(&pattern.to_proc)
60
+ when Symbol, Proc, Method then pattern.to_proc
36
61
 
37
62
  when Array then # enum.filter [:even?, :positive?, :cool?, proc { |n| n < 10 }]
38
- pattern.reduce(self) do |chain, local_pattern|
39
- chain.select(&local_pattern.to_proc)
63
+ proc do |e|
64
+ pattern.all? { |condition| filter_condition(condition).call(e) }
40
65
  end
41
66
 
42
67
  when Hash then # enum.filter :to_i => :even?, :ceil => :odd?
43
- pattern.reduce(self) do |chain, pair|
44
- attr, local_pattern = pair.map(&:to_proc)
45
-
46
- chain.select do |element|
47
- local_pattern.call(attr.call(element))
68
+ proc do |e|
69
+ pattern.all? do |attribute, condition|
70
+ filter_condition(condition).call(attribute.to_proc.call(e))
48
71
  end
49
72
  end
50
73
 
51
- when TrueClass, FalseClass then select { |e| !!e == pattern }
74
+ when TrueClass, FalseClass then proc { |e| !!e == pattern }
52
75
 
53
- else select { |e| pattern === e } # otherwise - String, Regexp, Numeric etc.
76
+ else proc { |e| pattern === e } # otherwise - String, Regexp, Numeric etc.
54
77
  end
55
-
56
- # also transform elements if block given
57
- block ? filtered.map(&block) : filtered
58
78
  end
59
-
60
- end
79
+ end
@@ -1,3 +1,3 @@
1
1
  module Filter
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -53,4 +53,8 @@ describe Enumerable do
53
53
  [0, false, 2, nil].filter(true).should == [0, 2]
54
54
  [0, false, 2, nil].filter(false).should == [false, nil]
55
55
  end
56
+
57
+ it "should match using OR operator" do
58
+ [0, 2, 3, 4].filter(:zero?, :odd?).should == [0, 3]
59
+ end
56
60
  end
metadata CHANGED
@@ -1,52 +1,48 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: filter
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 3
9
- version: 0.0.3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Alexey Mikhaylov
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-12-12 00:00:00 +06:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2011-12-12 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rspec
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &20615240 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
31
22
  type: :development
32
- version_requirements: *id001
33
- description: "== Synopsys\n\
34
- Enumerable#filter - extended Enumerable#select\n\n\
35
- == Examples\n\
36
- String filter (acts like Enumerable#grep):\n [1, 2, 3, 'ab'].filter(/a/) # => ['ab']\n [1, 2, 3, '3'].filter('3') # => ['3']\n\n\
37
- You can pass a <tt>Proc</tt> or <tt>Symbol</tt>. Methods and blocks are allowed too:\n [1, 2, 3].filter(&:even?) # => [2]\n [1, 2, 3].filter(:even?) # => [2]\n [1, 2, 4].filter { |num| num.even? } # => [2, 4]\n\n\
38
- <tt>Enumerable#filter</tt> can match against enumerable items attributes. Like this:\n [1, 2, 3, 4.2].filter :to_i => :even? # => [2, 4]\n\n\
39
- If the block is supplied, each matching element is passed to it, and the block\xE2\x80\x99s result is stored in the output enumerator.\n [1, 2, 4].filter(&:even?) { |n| n + 1 } # => [3, 5]\n\n\
40
- <tt>Enumerable#filter</tt> also accepts <tt>true</tt> or <tt>false</tt> as argument:\n [0, false, 2, nil].filter(true) # => [0, 2]\n [0, false, 2, nil].filter(false) # => [false, nil]\n"
41
- email:
23
+ prerelease: false
24
+ version_requirements: *20615240
25
+ description: ! "== Synopsys\n<code>Enumerable#filter</code> - extended <code>Enumerable#select</code>\n\n==
26
+ Examples\nString filter (acts like <code>Enumerable#grep</code>):\n [1, 2, 3, 'ab'].filter(/a/)
27
+ \ # => ['ab']\n [1, 2, 3, '3'].filter('3') # => ['3']\n\nYou
28
+ can pass a <code>Proc</code> or <code>Symbol</code>. Methods and blocks are allowed
29
+ too:\n [1, 2, 3].filter(&:even?) # => [2]\n [1, 2, 3].filter(:even?)
30
+ \ # => [2]\n [1, 2, 4].filter { |num| num.even? } # => [2, 4]\n\n<code>Enumerable#filter</code>
31
+ can match against enumerable items attributes. Like this:\n [1, 2, 3, 4.2].filter
32
+ :to_i => :even? # => [2, 4]\n\nIf the block is supplied, each matching element
33
+ is passed to it, and the block's result is stored in the output array.\n [1, 2,
34
+ 4].filter(&:even?) { |n| n + 1 } # => [3, 5]\n\n<code>Enumerable#filter</code>
35
+ also accepts <code>true</code> or <code>false</code> as argument:\n [0, false,
36
+ 2, nil].filter(true) # => [0, 2]\n [0, false, 2, nil].filter(false) #
37
+ => [false, nil]\n\n<code>Enumerable#filter</code> also supports <code>OR</code>
38
+ operator!\nJust pass many patterns, they will be joined together with <code>OR</code>
39
+ operator.\n [0, 2, 3, 4].filter(:zero?, :odd?) # => [0, 3]"
40
+ email:
42
41
  - amikhailov83@gmail.com
43
42
  executables: []
44
-
45
43
  extensions: []
46
-
47
44
  extra_rdoc_files: []
48
-
49
- files:
45
+ files:
50
46
  - .gitignore
51
47
  - Gemfile
52
48
  - LICENSE
@@ -57,37 +53,28 @@ files:
57
53
  - lib/filter/version.rb
58
54
  - spec/filter_spec.rb
59
55
  - spec/test_helper.rb
60
- has_rdoc: true
61
56
  homepage: https://github.com/take-five/filter
62
57
  licenses: []
63
-
64
58
  post_install_message:
65
59
  rdoc_options: []
66
-
67
- require_paths:
60
+ require_paths:
68
61
  - lib
69
- required_ruby_version: !ruby/object:Gem::Requirement
62
+ required_ruby_version: !ruby/object:Gem::Requirement
70
63
  none: false
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- segments:
75
- - 0
76
- version: "0"
77
- required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
69
  none: false
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- segments:
83
- - 0
84
- version: "0"
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
85
74
  requirements: []
86
-
87
75
  rubyforge_project: filter
88
- rubygems_version: 1.3.7
76
+ rubygems_version: 1.8.10
89
77
  signing_key:
90
78
  specification_version: 3
91
79
  summary: Enumerable#filter - extended Enumerable#select combined with Enumerable#collect
92
80
  test_files: []
93
-