sleeping_king_studios-tools 0.2.0 → 0.3.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +40 -0
- data/lib/sleeping_king_studios/tools/array_tools.rb +119 -14
- data/lib/sleeping_king_studios/tools/string_tools.rb +25 -0
- data/lib/sleeping_king_studios/tools/version.rb +2 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2abf0235b1796184caa2b29cc3c2886d0b94f1b
|
4
|
+
data.tar.gz: 784bd7ea599838663906cde584cbcca474879ed6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9554e42f6ac9fc4e584849d808872828b2091efdc645a3c22d65403c474e786eedbcb6eb61440ae7991508ff571bd358f940f4fe67fe87d9842d4c54d77dedba
|
7
|
+
data.tar.gz: 57137dcbd88ef5ca51d071b69315a819c9a3e3d00c92d2d620a602eb032ea546c59bebba62b2c7139615c0ab4b4956053bf4a86121b1a7c3f5341ea428425936
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -18,6 +18,17 @@ Hi, I'm Rob Smith, a Ruby Engineer and the developer of this library. I use thes
|
|
18
18
|
|
19
19
|
Tools for working with array-like enumerable objects.
|
20
20
|
|
21
|
+
#### `#bisect`
|
22
|
+
|
23
|
+
Separates the array into two arrays, the first containing all items in the original array that matches the provided block, and the second containing all items in the original array that do not match the provided block.
|
24
|
+
|
25
|
+
original = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
26
|
+
selected, rejected = ArrayTools.bisect(original) { |item| item.even? }
|
27
|
+
selected
|
28
|
+
#=> [0, 2, 4, 6, 8]
|
29
|
+
rejected
|
30
|
+
#=> [1, 3, 5, 7, 9]
|
31
|
+
|
21
32
|
#### `#count_values`
|
22
33
|
|
23
34
|
Counts the number of times each value appears in the array, or if a block is given, calls the block with each item and counts the number of times each result appears.
|
@@ -64,6 +75,31 @@ Accepts a list of values and returns a human-readable string of the values, with
|
|
64
75
|
ArrayTools.humanize_list(['spam', 'eggs', 'bacon', 'spam'])
|
65
76
|
#=> 'spam, eggs, bacon, and spam'
|
66
77
|
|
78
|
+
#### `#splice`
|
79
|
+
|
80
|
+
Accepts an array, a start value, a number of items to delete, and zero or more items to insert at that index. Deletes the specified number of items, then inserts the given items at the index and returns the array of deleted items.
|
81
|
+
|
82
|
+
# Deleting items from an Array
|
83
|
+
values = %w(katana wakizashi tachi daito shoto)
|
84
|
+
ArrayTools.splice values, 1, 2
|
85
|
+
#=> ['wakizashi', 'tachi']
|
86
|
+
values
|
87
|
+
#=> ['katana', 'daito', 'shoto']
|
88
|
+
|
89
|
+
# Inserting items into an Array
|
90
|
+
values = %w(longsword broadsword claymore)
|
91
|
+
ArrayTools.splice values, 1, 0, 'zweihänder'
|
92
|
+
#=> []
|
93
|
+
values
|
94
|
+
#=> ['longsword', 'zweihänder', 'broadsword', 'claymore']
|
95
|
+
|
96
|
+
# Inserting and deleting items
|
97
|
+
values = %w(shortbow longbow crossbow)
|
98
|
+
ArrayTools.splice values, 2, 1, 'arbalest', 'chu-ko-nu'
|
99
|
+
#=> ['crossbow']
|
100
|
+
values
|
101
|
+
#=> ['shortbow', 'longbow', 'arbalest', 'chu-ko-nu']
|
102
|
+
|
67
103
|
### Hash Tools
|
68
104
|
|
69
105
|
Tools for working with array-like enumerable objects.
|
@@ -202,6 +238,10 @@ Returns the singular or the plural value, depending on the provided item count.
|
|
202
238
|
StringTools.pluralize 4, 'light', 'lights'
|
203
239
|
#=> 'lights'
|
204
240
|
|
241
|
+
#### '#underscore'
|
242
|
+
|
243
|
+
Converts a mixed-case string expression to a lowercase, underscore separated string, as per ActiveSupport::Inflector#underscore.
|
244
|
+
|
205
245
|
## Additional Features
|
206
246
|
|
207
247
|
### Semantic Version
|
@@ -8,19 +8,57 @@ module SleepingKingStudios::Tools
|
|
8
8
|
module ArrayTools
|
9
9
|
extend self
|
10
10
|
|
11
|
-
#
|
11
|
+
# Separates the array into two arrays, the first containing all items in the
|
12
|
+
# original array that matches the provided block, and the second containing
|
13
|
+
# all items in the original array that do not match the provided block.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# selected, rejected = ArrayTools.bisect([*0...10]) { |item| item.even? }
|
17
|
+
# selected
|
18
|
+
# #=> [0, 2, 4, 6, 8]
|
19
|
+
# rejected
|
20
|
+
# #=> [1, 3, 5, 7, 9]
|
21
|
+
#
|
22
|
+
# @param [Array<Object>] ary The array to bisect.
|
23
|
+
#
|
24
|
+
# @yieldparam item [Object] An item in the array to matched.
|
25
|
+
#
|
26
|
+
# @yieldreturn [Boolean] True if the item matches the criteria, otherwise
|
27
|
+
# false.
|
28
|
+
#
|
29
|
+
# @raise ArgumentError If the first argument is not an Array-like object or
|
30
|
+
# if no block is given.
|
31
|
+
#
|
32
|
+
# @return [Array<Array<Object>>] An array containing two arrays.
|
33
|
+
def bisect ary, &block
|
34
|
+
require_array! ary
|
35
|
+
|
36
|
+
raise ArgumentError.new('no block given') unless block_given?
|
37
|
+
|
38
|
+
selected, rejected = [], []
|
39
|
+
|
40
|
+
ary.each do |item|
|
41
|
+
(yield(item) ? selected : rejected) << item
|
42
|
+
end # each
|
43
|
+
|
44
|
+
[selected, rejected]
|
45
|
+
end # method bisect
|
46
|
+
|
47
|
+
# @overload count_values(ary)
|
12
48
|
# Counts the number of times each value appears in the enumerable object.
|
13
49
|
#
|
14
50
|
# @example
|
15
51
|
# ArrayTools.count_values([1, 1, 1, 2, 2, 3])
|
16
52
|
# #=> { 1 => 3, 2 => 2, 3 => 1 }
|
17
53
|
#
|
18
|
-
# @param [Array<Object>]
|
54
|
+
# @param [Array<Object>] ary The values to count.
|
55
|
+
#
|
56
|
+
# @raise ArgumentError If the first argument is not an Array-like object.
|
19
57
|
#
|
20
58
|
# @return [Hash{Object, Integer}] The number of times each value appears
|
21
59
|
# in the enumerable object.
|
22
60
|
#
|
23
|
-
# @overload count_values(
|
61
|
+
# @overload count_values(ary, &block)
|
24
62
|
# Calls the block with each item and counts the number of times each
|
25
63
|
# result appears.
|
26
64
|
#
|
@@ -28,15 +66,20 @@ module SleepingKingStudios::Tools
|
|
28
66
|
# ArrayTools.count_values([1, 1, 1, 2, 2, 3]) { |i| i ** 2 }
|
29
67
|
# #=> { 1 => 3, 4 => 2, 9 => 1 }
|
30
68
|
#
|
31
|
-
# @param [Array<Object>]
|
69
|
+
# @param [Array<Object>] ary The values to count.
|
70
|
+
#
|
71
|
+
# @yieldparam item [Object] An item in the array to matched.
|
72
|
+
#
|
73
|
+
# @raise ArgumentError If the first argument is not an Array-like object.
|
32
74
|
#
|
33
75
|
# @return [Hash{Object, Integer}] The number of times each result
|
34
76
|
# appears.
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
77
|
+
def count_values ary, &block
|
78
|
+
require_array! ary
|
79
|
+
|
80
|
+
ary.each.with_object({}) do |item, hsh|
|
39
81
|
value = block_given? ? block.call(item) : item
|
82
|
+
|
40
83
|
hsh[value] = hsh.fetch(value, 0) + 1
|
41
84
|
end # each
|
42
85
|
end # method count_values
|
@@ -48,6 +91,8 @@ module SleepingKingStudios::Tools
|
|
48
91
|
#
|
49
92
|
# @return [Array] The copy of the array.
|
50
93
|
def deep_dup ary
|
94
|
+
require_array! ary
|
95
|
+
|
51
96
|
ary.map { |obj| ObjectTools.deep_dup obj }
|
52
97
|
end # method deep_dup
|
53
98
|
|
@@ -74,7 +119,7 @@ module SleepingKingStudios::Tools
|
|
74
119
|
# ArrayTools.humanize_list(['spam', 'eggs', 'bacon', 'spam'], :last_separator => ' or ')
|
75
120
|
# #=> 'spam, eggs, bacon, or spam'
|
76
121
|
#
|
77
|
-
# @param [Array<String>]
|
122
|
+
# @param [Array<String>] ary The list of values to format. Will be
|
78
123
|
# coerced to strings using #to_s.
|
79
124
|
# @param [Hash] options Optional configuration hash.
|
80
125
|
# @option options [String] :last_separator The value to use to separate
|
@@ -85,18 +130,22 @@ module SleepingKingStudios::Tools
|
|
85
130
|
# of values before the last in lists of length 3 or greater. Defaults to
|
86
131
|
# ", " (note the trailing space).
|
87
132
|
#
|
133
|
+
# @raise ArgumentError If the first argument is not an Array-like object.
|
134
|
+
#
|
88
135
|
# @return [String] The formatted string.
|
89
|
-
def humanize_list
|
136
|
+
def humanize_list ary, options = {}
|
137
|
+
require_array! ary
|
138
|
+
|
90
139
|
separator = options.fetch(:separator, ', ')
|
91
140
|
last_separator = options.fetch(:last_separator, ' and ')
|
92
141
|
|
93
|
-
case
|
142
|
+
case ary.count
|
94
143
|
when 0
|
95
144
|
''
|
96
145
|
when 1
|
97
|
-
|
146
|
+
ary.first.to_s
|
98
147
|
when 2
|
99
|
-
"#{
|
148
|
+
"#{ary[0]}#{last_separator}#{ary[1]}"
|
100
149
|
else
|
101
150
|
if last_separator =~ /\A,?\s*/
|
102
151
|
last_separator = last_separator.sub /\A,?\s*/, separator
|
@@ -104,8 +153,64 @@ module SleepingKingStudios::Tools
|
|
104
153
|
last_separator = "#{separator}#{last_separator}"
|
105
154
|
end # if-else
|
106
155
|
|
107
|
-
"#{
|
156
|
+
"#{ary[0...-1].join(separator)}#{last_separator}#{ary.last}"
|
108
157
|
end # case
|
109
158
|
end # method humanize_list
|
159
|
+
|
160
|
+
# Accepts an array, a start value, a number of items to delete, and zero or
|
161
|
+
# more items to insert at that index. Deletes the specified number of items,
|
162
|
+
# then inserts the given items at the index and returns the array of deleted
|
163
|
+
# items.
|
164
|
+
#
|
165
|
+
# @example Deleting items from an Array
|
166
|
+
# values = %w(katana wakizashi tachi daito shoto)
|
167
|
+
# ArrayTools.splice values, 1, 2
|
168
|
+
# #=> ['wakizashi', 'tachi']
|
169
|
+
# values
|
170
|
+
# #=> ['katana', 'daito', 'shoto']
|
171
|
+
#
|
172
|
+
# @example Inserting items into an Array
|
173
|
+
# values = %w(longsword broadsword claymore)
|
174
|
+
# ArrayTools.splice values, 1, 0, 'zweihänder'
|
175
|
+
# #=> []
|
176
|
+
# values
|
177
|
+
# #=> ['longsword', 'zweihänder', 'broadsword', 'claymore']
|
178
|
+
#
|
179
|
+
# @example Inserting and deleting items
|
180
|
+
# values = %w(shortbow longbow crossbow)
|
181
|
+
# ArrayTools.splice values, 2, 1, 'arbalest', 'chu-ko-nu'
|
182
|
+
# #=> ['crossbow']
|
183
|
+
# values
|
184
|
+
# #=> ['shortbow', 'longbow', 'arbalest', 'chu-ko-nu']
|
185
|
+
#
|
186
|
+
# @param [Array<Object>] ary The array to splice.
|
187
|
+
# @param [Integer] start The starting index to delete or insert values from
|
188
|
+
# or into. If negative, counts backward from the end of the array.
|
189
|
+
# @param [Integer] delete_count The number of items to delete.
|
190
|
+
# @param [Array<Object>] insert The items to insert, if any.
|
191
|
+
#
|
192
|
+
# @raise ArgumentError If the first argument is not an Array-like object.
|
193
|
+
#
|
194
|
+
# @return [Array<Object>] The deleted items, or an empty array if no items
|
195
|
+
# were deleted.
|
196
|
+
def splice ary, start, delete_count, *insert
|
197
|
+
require_array! ary
|
198
|
+
|
199
|
+
start = start < 0 ? start + ary.count : start
|
200
|
+
range = start...(start + delete_count)
|
201
|
+
deleted = ary[range]
|
202
|
+
|
203
|
+
ary[range] = insert
|
204
|
+
|
205
|
+
deleted
|
206
|
+
end # method splice
|
207
|
+
|
208
|
+
private
|
209
|
+
|
210
|
+
def require_array! value
|
211
|
+
methods = %i([] count each)
|
212
|
+
|
213
|
+
raise ArgumentError.new('argument must be an array') unless methods.reduce(true) { |memo, method_name| memo && value.respond_to?(method_name) }
|
214
|
+
end # method require_array
|
110
215
|
end # module
|
111
216
|
end # module
|
@@ -23,5 +23,30 @@ module SleepingKingStudios::Tools
|
|
23
23
|
def pluralize count, single, plural
|
24
24
|
1 == count ? single : plural
|
25
25
|
end # method pluralize
|
26
|
+
|
27
|
+
# Converts a mixed-case string expression to a lowercase, underscore
|
28
|
+
# separated string.
|
29
|
+
#
|
30
|
+
# @param str [String] The string to convert.
|
31
|
+
#
|
32
|
+
# @return [String] The converted string.
|
33
|
+
#
|
34
|
+
# @see ActiveSupport::Inflector#underscore.
|
35
|
+
def underscore str
|
36
|
+
require_string! str
|
37
|
+
|
38
|
+
str = str.dup
|
39
|
+
str.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
40
|
+
str.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
41
|
+
str.tr!("-", "_")
|
42
|
+
str.downcase!
|
43
|
+
str
|
44
|
+
end # method underscore
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def require_string! value
|
49
|
+
raise ArgumentError.new('argument must be a string') unless value.is_a?(String)
|
50
|
+
end # method require_array
|
26
51
|
end # module
|
27
52
|
end # module
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sleeping_king_studios-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0.alpha
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob "Merlin" Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03
|
11
|
+
date: 2016-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -114,9 +114,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
114
|
version: '0'
|
115
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
116
|
requirements:
|
117
|
-
- - "
|
117
|
+
- - ">"
|
118
118
|
- !ruby/object:Gem::Version
|
119
|
-
version:
|
119
|
+
version: 1.3.1
|
120
120
|
requirements: []
|
121
121
|
rubyforge_project:
|
122
122
|
rubygems_version: 2.5.1
|