list-utils 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Kevin C. Baird
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1 @@
1
+ TODO
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+ # list_utils.rb
3
+
4
+ # Adds several syntactic sugar methods and method aliases, inspired by CPAN's
5
+ # List::Util and List::MoreUtils modules, and the Haskell 98 Standard Prelude.
6
+ class Array
7
+
8
+ # Returns a copy of the Array with the first <i>count</i> items missing.
9
+ def drop(count)
10
+ self[ count .. -1 ]
11
+ end
12
+
13
+ # Returns a copy of the Array from the first point at which <i>&blk</i>
14
+ # is <b>false</b> to the end.
15
+ def drop_while(&blk)
16
+ return self unless yield head
17
+ tail ? tail.drop_while(&blk) : []
18
+ end
19
+
20
+ # Returns a copy of the Array from the first point at which <i>&blk</i>
21
+ # is <b>true</b> to the end.
22
+ def drop_until(&blk)
23
+ return self if yield head
24
+ tail ? tail.drop_until(&blk) : []
25
+ end
26
+
27
+ alias_method :elem?, :include?
28
+
29
+ # Returns the number of elements for which <i>&blk</i> is <b>false</b>.
30
+ def false_count(&blk)
31
+ size - true_count(&blk)
32
+ end
33
+
34
+ alias_method :filter, :find_all
35
+ alias_method :find_first, :detect
36
+
37
+ # Performs the method identified by <i>method_sym</i> on each element
38
+ # with the following element as the single argument.
39
+ # * (0..9).to_a.fold(:+) = 45
40
+ # * [0, 1].fold(:+) = 1
41
+ # * [0, 1].fold(:*) = 0
42
+ # * 'hello'.split('').fold(:+) = 'hello'
43
+ def fold(method_sym)
44
+ output = first
45
+ (self - [first]).each do |e|
46
+ output = output.send(method_sym, e)
47
+ end
48
+ output
49
+ end
50
+
51
+ alias_method :head, :first
52
+
53
+ # Returns <b>true</b> if none of the elements satisfy <i>&blk</i>,
54
+ # <b>false</b> otherwise.
55
+ def none?(&blk)
56
+ not any?(&blk)
57
+ end
58
+
59
+ # Returns <b>true</b> if any of the elements do not satisfy <i>&blk</i>,
60
+ # <b>false</b> otherwise.
61
+ def not_all?(&blk)
62
+ not all?(&blk)
63
+ end
64
+
65
+ # Returns a randomly-chosen element of the Array.
66
+ def rand_element
67
+ shuffle[0]
68
+ end
69
+
70
+ alias_method :reduce, :fold
71
+
72
+ # Returns all elements of the Array in order except the first.
73
+ def rest
74
+ self[ 1 .. -1 ]
75
+ end
76
+
77
+ # Returns a copy of the Array in random order.
78
+ def shuffle
79
+ sort_by { rand }
80
+ end
81
+
82
+ # Syntactic sugar for <b>fold(:+)</b>.
83
+ def sum
84
+ fold(:+)
85
+ end
86
+
87
+ alias_method :tail, :rest
88
+
89
+ # Returns the first <i>count</i> elements of the Array.
90
+ def take(count)
91
+ self[0 .. (count-1) ]
92
+ end
93
+
94
+ alias_method :take_while, :drop_until
95
+ alias_method :take_until, :drop_while
96
+
97
+ # Returns the number of elements for which <i>&blk</i> is <b>true</b>.
98
+ def true_count(&blk)
99
+ filter(&blk).size
100
+ end
101
+
102
+ end
103
+
104
+ if (__FILE__ == $0)
105
+ a = (0..9).to_a
106
+ non_zeroes = a.drop_while { |x| x.zero? }
107
+ puts %Q[non_zeroes = #{non_zeroes.inspect}]
108
+ above_five = a.drop_while { |x| x <= 5 }
109
+ puts %Q[above 5 = #{above_five.inspect}]
110
+ above_five = a.drop_until { |x| x > 5 }
111
+ puts %Q[above 5 = #{above_five.inspect}]
112
+ below_five = a.take_while { |x| x < 5 }
113
+ puts %Q[below 5 = #{below_five.inspect}]
114
+ below_five = a.take_until { |x| x >= 5 }
115
+ puts %Q[below 5 = #{below_five.inspect}]
116
+ first_six = a.take(6)
117
+ puts %Q[first 6 = #{first_six.inspect}]
118
+ end
@@ -0,0 +1,231 @@
1
+ #!/usr/bin/env ruby
2
+ # test_list_utils.rb
3
+
4
+ require %q[lib/list_utils]
5
+ require %q[test/unit]
6
+
7
+ class Tester < Test::Unit::TestCase
8
+
9
+ EMPTY_STRING = %q[]
10
+ EMPTY_ARRAY = []
11
+ DIGITS = (0..9).to_a
12
+ HELLO = %q[hello]
13
+ HELLOA = HELLO.split(EMPTY_STRING)
14
+ VOWELS = %w[a e i o u y]
15
+
16
+ LAMBDA = {
17
+ :above4? => lambda { |x| x > 4 },
18
+ :above10? => lambda { |x| x > 10 },
19
+ :below5? => lambda { |x| x < 5 },
20
+ :digit? => lambda { |x| DIGITS.include?(x) },
21
+ :vowel? => lambda { |x| VOWELS.include?(x) },
22
+ :not_vowel? => lambda { |x| not VOWELS.include?(x) },
23
+ }
24
+
25
+ COMPARISONS = [:above4?, :above10?, :below5?]
26
+ NON_COMPARISONS = LAMBDA.keys - COMPARISONS
27
+
28
+ def test_drop
29
+ assert_equal EMPTY_ARRAY, EMPTY_ARRAY.drop(0)
30
+ assert_equal DIGITS, DIGITS.drop(0)
31
+ assert_equal EMPTY_ARRAY, DIGITS.drop(DIGITS.size)
32
+ assert_equal (1..9).to_a, DIGITS.drop(1)
33
+ assert_equal %w[l l o], HELLOA.drop(2)
34
+ end
35
+
36
+ def test_drop_while
37
+ COMPARISONS.each do |lk|
38
+ assert_raise(ArgumentError) { HELLOA.drop_while( &LAMBDA[lk] ) }
39
+ end
40
+ NON_COMPARISONS.each { |lk| assert_equal EMPTY_ARRAY, EMPTY_ARRAY.drop_while( &LAMBDA[lk] ) }
41
+ assert_equal DIGITS, DIGITS.drop_while( &LAMBDA[:vowel?] )
42
+ assert_equal HELLOA, HELLOA.drop_while( &LAMBDA[:vowel?] )
43
+ assert_equal EMPTY_ARRAY, DIGITS.drop_while( &LAMBDA[:not_vowel?] )
44
+ assert_equal HELLOA.tail, HELLOA.drop_while( &LAMBDA[:not_vowel?] )
45
+ assert_equal DIGITS.filter(&LAMBDA[:above4?]), DIGITS.drop_while( &LAMBDA[:below5?] )
46
+ end
47
+
48
+ def test_drop_until
49
+ COMPARISONS.each do |lk|
50
+ assert_raise(NoMethodError) { EMPTY_ARRAY.drop_until( &LAMBDA[lk] ) }
51
+ end
52
+ NON_COMPARISONS.each { |lk| assert_equal EMPTY_ARRAY.drop_until( &LAMBDA[lk] ), EMPTY_ARRAY }
53
+ assert_equal EMPTY_ARRAY, DIGITS.drop_until( &LAMBDA[:vowel?] )
54
+ assert_equal HELLOA.tail, HELLOA.drop_until( &LAMBDA[:vowel?] )
55
+ assert_equal DIGITS, DIGITS.drop_until( &LAMBDA[:not_vowel?] )
56
+ assert_equal HELLOA, HELLOA.drop_until( &LAMBDA[:not_vowel?] )
57
+ assert_equal DIGITS.filter( &LAMBDA[:above4?] ), DIGITS.drop_until( &LAMBDA[:above4?] )
58
+ end
59
+
60
+ def test_elem
61
+ assert_equal false, EMPTY_ARRAY.elem?(0)
62
+ assert_equal false, EMPTY_ARRAY.elem?(nil)
63
+ assert DIGITS.elem?(0)
64
+ HELLOA.each { |char| assert HELLOA.elem?(char) }
65
+ assert_equal false, DIGITS.elem?(EMPTY_STRING)
66
+ assert_equal false, DIGITS.elem?(nil)
67
+ assert_equal false, [].elem?(nil)
68
+ assert_equal false, [].elem?(EMPTY_STRING)
69
+ assert_equal false, HELLOA.elem?(0)
70
+ end
71
+
72
+ def test_false_count
73
+ LAMBDA.keys.each do |lk|
74
+ assert_equal 0, EMPTY_ARRAY.false_count( &LAMBDA[lk] )
75
+ end
76
+ assert_equal 0, DIGITS.false_count( &LAMBDA[:digit?] )
77
+ assert_equal 3, HELLOA.false_count( &LAMBDA[:vowel?] )
78
+ assert_equal 2, HELLOA.false_count( &LAMBDA[:not_vowel?] )
79
+ assert_equal DIGITS.size, DIGITS.false_count( &LAMBDA[:vowel?] )
80
+ assert_equal HELLOA.size, HELLOA.false_count( &LAMBDA[:digit?] )
81
+ end
82
+
83
+ def test_filter
84
+ COMPARISONS.each do |lk|
85
+ assert_raise(ArgumentError) { HELLOA.drop_while( &LAMBDA[lk] ) }
86
+ end
87
+ LAMBDA.keys.each { |lk| assert_equal EMPTY_ARRAY.filter( &LAMBDA[lk] ), EMPTY_ARRAY }
88
+ assert_equal DIGITS, DIGITS.filter( &LAMBDA[:digit?] )
89
+ assert_equal EMPTY_ARRAY, HELLOA.filter( &LAMBDA[:digit?] )
90
+ assert_equal DIGITS, DIGITS.filter( &LAMBDA[:not_vowel?] )
91
+ assert_equal %w[h l l], HELLOA.filter( &LAMBDA[:not_vowel?] )
92
+ assert_equal EMPTY_ARRAY, DIGITS.filter( &LAMBDA[:vowel?] )
93
+ assert_equal %w[e o], HELLOA.filter( &LAMBDA[:vowel?] )
94
+ end
95
+
96
+ def test_find_first
97
+ COMPARISONS.each do |lk|
98
+ assert_raise(ArgumentError) { HELLOA.find_first( &LAMBDA[lk] ) }
99
+ end
100
+ NON_COMPARISONS.each { |lk| assert_nil EMPTY_ARRAY.find_first( &LAMBDA[lk] ) }
101
+ assert_equal 5, DIGITS.find_first( &LAMBDA[:above4?] )
102
+ assert_nil DIGITS.find_first( &LAMBDA[:above10?] )
103
+ assert_equal %q[e], HELLOA.find_first( &LAMBDA[:vowel?] )
104
+ assert_equal %q[h], HELLOA.find_first( &LAMBDA[:not_vowel?] )
105
+ end
106
+
107
+ def test_fold
108
+ assert_equal 45, DIGITS.fold(:+)
109
+ assert_equal 0, DIGITS.fold(:*)
110
+ assert_equal 45, DIGITS.tail.fold(:+)
111
+ assert_equal 362880, DIGITS.tail.fold(:*)
112
+ assert_equal HELLO, HELLOA.fold(:+), HELLO
113
+ end
114
+
115
+ def test_head
116
+ assert_equal DIGITS[0], DIGITS.head
117
+ assert_equal 0, DIGITS.head
118
+ assert_nil EMPTY_ARRAY.head
119
+ end
120
+
121
+ def test_none
122
+ COMPARISONS.each do |lk|
123
+ assert_raise(ArgumentError) { HELLOA.none?( &LAMBDA[lk] ) }
124
+ end
125
+ LAMBDA.keys.each { |lk| assert_equal true, EMPTY_ARRAY.none?( &LAMBDA[lk] ) }
126
+ assert_equal true, DIGITS.none?( &LAMBDA[:above10?] )
127
+ assert_equal false, DIGITS.none?( &LAMBDA[:above4?] )
128
+ assert_equal false, DIGITS.none?( &LAMBDA[:below5?] )
129
+ assert_equal false, DIGITS.none?( &LAMBDA[:digit?] )
130
+ assert_equal true, DIGITS.none?( &LAMBDA[:vowel?] )
131
+ assert_equal false, DIGITS.none?( &LAMBDA[:not_vowel?] )
132
+ assert_equal true, HELLOA.none?( &LAMBDA[:digit?] )
133
+ assert_equal false, HELLOA.none?( &LAMBDA[:vowel?] )
134
+ assert_equal false, HELLOA.none?( &LAMBDA[:not_vowel?] )
135
+ end
136
+
137
+ def test_not_all
138
+ COMPARISONS.each do |lk|
139
+ assert_equal true, DIGITS.not_all?( &LAMBDA[lk] )
140
+ assert_raise(ArgumentError) { HELLOA.not_all?( &LAMBDA[lk] ) }
141
+ end
142
+ LAMBDA.keys.each { |lk| assert_equal false, EMPTY_ARRAY.not_all?( &LAMBDA[lk] ) }
143
+ assert_equal false, DIGITS.not_all?( &LAMBDA[:digit?] )
144
+ assert_equal true, DIGITS.not_all?( &LAMBDA[:vowel?] )
145
+ assert_equal false, DIGITS.not_all?( &LAMBDA[:not_vowel?] )
146
+ assert_equal true, HELLOA.not_all?( &LAMBDA[:digit?] )
147
+ assert_equal true, HELLOA.not_all?( &LAMBDA[:vowel?] )
148
+ assert_equal true, HELLOA.not_all?( &LAMBDA[:not_vowel?] )
149
+ end
150
+
151
+ def test_rand_element
152
+ [DIGITS, HELLOA].each do |a|
153
+ 100.times { assert a.include?(a.rand_element) }
154
+ end
155
+ assert_nil EMPTY_ARRAY.rand_element
156
+ end
157
+
158
+ def test_reduce
159
+ #TODO
160
+ end
161
+
162
+ def test_rest
163
+ #TODO
164
+ end
165
+
166
+ def test_shuffle
167
+ [DIGITS, HELLOA].each do |a|
168
+ 100.times { assert_equal a.sort, a.shuffle.sort }
169
+ end
170
+ assert_equal EMPTY_ARRAY, EMPTY_ARRAY.shuffle
171
+ end
172
+
173
+ def test_sum
174
+ assert_equal nil, EMPTY_ARRAY.sum
175
+ assert_equal 45, DIGITS.sum
176
+ assert_equal 10, DIGITS.filter( &LAMBDA[:below5?] ).sum
177
+ assert_equal HELLO, HELLOA.sum
178
+ end
179
+
180
+ def test_tail
181
+ assert_nil EMPTY_ARRAY.tail
182
+ assert_equal (1..9).to_a, DIGITS.tail
183
+ assert_equal %w[e l l o], HELLOA.tail
184
+
185
+ end
186
+
187
+ def test_take
188
+ 0.upto(10) { |x| assert_equal EMPTY_ARRAY, EMPTY_ARRAY.take(x) }
189
+ [DIGITS, HELLOA].each do |a|
190
+ assert_equal [a.head], a.take(1)
191
+ assert_equal [a.head, a.tail.head], a.take(2)
192
+ assert_equal [a.head, a.tail.head, a.tail.tail.head], a.take(3)
193
+ end
194
+ end
195
+
196
+ def test_take_while
197
+ COMPARISONS.each do |lk|
198
+ assert_raise(NoMethodError) { EMPTY_ARRAY.take_while( &LAMBDA[lk] ) }
199
+ end
200
+ NON_COMPARISONS.each { |lk| assert_equal EMPTY_ARRAY.take_while( &LAMBDA[lk] ), EMPTY_ARRAY }
201
+ assert_equal EMPTY_ARRAY, DIGITS.take_while( &LAMBDA[:vowel?] )
202
+ assert_equal HELLOA.tail, HELLOA.take_while( &LAMBDA[:vowel?] )
203
+ assert_equal DIGITS, DIGITS.take_while( &LAMBDA[:not_vowel?] )
204
+ assert_equal HELLOA, HELLOA.take_while( &LAMBDA[:not_vowel?] )
205
+ assert_equal DIGITS.filter( &LAMBDA[:above4?] ), DIGITS.take_while( &LAMBDA[:above4?] )
206
+ end
207
+
208
+ def test_take_until
209
+ COMPARISONS.each do |lk|
210
+ assert_raise(ArgumentError) { HELLOA.take_until( &LAMBDA[lk] ) }
211
+ end
212
+ NON_COMPARISONS.each { |lk| assert_equal EMPTY_ARRAY, EMPTY_ARRAY.take_until( &LAMBDA[lk] ) }
213
+ assert_equal DIGITS, DIGITS.take_until( &LAMBDA[:vowel?] )
214
+ assert_equal HELLOA, HELLOA.take_until( &LAMBDA[:vowel?] )
215
+ assert_equal EMPTY_ARRAY, DIGITS.take_until( &LAMBDA[:not_vowel?] )
216
+ assert_equal HELLOA.tail, HELLOA.take_until( &LAMBDA[:not_vowel?] )
217
+ assert_equal DIGITS.filter(&LAMBDA[:above4?]), DIGITS.take_until( &LAMBDA[:below5?] )
218
+ end
219
+
220
+ def test_true_count
221
+ LAMBDA.keys.each do |lk|
222
+ assert_equal 0, EMPTY_ARRAY.true_count( &LAMBDA[lk] )
223
+ end
224
+ assert_equal DIGITS.size, DIGITS.true_count( &LAMBDA[:digit?] )
225
+ assert_equal 2, HELLOA.true_count( &LAMBDA[:vowel?] )
226
+ assert_equal 3, HELLOA.true_count( &LAMBDA[:not_vowel?] )
227
+ assert_equal 0, DIGITS.true_count( &LAMBDA[:vowel?] )
228
+ assert_equal 0, HELLOA.true_count( &LAMBDA[:digit?] )
229
+ end
230
+
231
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: list-utils
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2007-12-05 00:00:00 -05:00
8
+ summary: A collection of syntactically sweet Array methods
9
+ require_paths:
10
+ - lib
11
+ email: kcbaird@world.oberlin.edu
12
+ homepage: http://list-utils-gem.rubyforge.org
13
+ rubyforge_project:
14
+ description: list-utils adds several list-related methods and method aliases to the Array class. Among its inspirations are the List::Util and List::MoreUtils CPAN modules for Perl at http://cpan.org and the Haskell 98 Prelude (http://www.haskell.org/onlinereport/prelude-index.html).
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Kevin C. Baird
31
+ files:
32
+ - lib/list-utils.rb
33
+ - tests/list-utils-test.rb
34
+ - MIT-LICENSE
35
+ - README
36
+ test_files:
37
+ - tests/list-utils-test.rb
38
+ rdoc_options: []
39
+
40
+ extra_rdoc_files:
41
+ - MIT-LICENSE
42
+ - README
43
+ executables: []
44
+
45
+ extensions: []
46
+
47
+ requirements: []
48
+
49
+ dependencies: []
50
+