list-utils 0.1

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.
@@ -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
+