facets 2.5.0 → 2.5.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.
- data/AUTHORS +1 -1
- data/CHANGES +28 -45
- data/MANIFEST +35 -4
- data/README +3 -14
- data/RELEASE +36 -70
- data/VERSION +1 -1
- data/doc/archive/RELEASE-2.5.0 +83 -0
- data/doc/log/basic_stats/index.html +4 -4
- data/doc/log/changelog.html +509 -2
- data/doc/log/changelog.txt +130 -1522
- data/doc/rdoc/core/classes/Array.html +366 -141
- data/doc/rdoc/core/classes/Binding.html +45 -45
- data/doc/rdoc/core/classes/Class.html +38 -38
- data/doc/rdoc/core/classes/Comparable.html +26 -26
- data/doc/rdoc/core/classes/Enumerable.html +174 -170
- data/doc/rdoc/core/classes/Enumerable/Enumerator.html +130 -0
- data/doc/rdoc/core/classes/Enumerator.html +132 -0
- data/doc/rdoc/core/classes/Exception.html +8 -8
- data/doc/rdoc/core/classes/File.html +58 -58
- data/doc/rdoc/core/classes/FileTest.html +4 -4
- data/doc/rdoc/core/classes/Float.html +8 -8
- data/doc/rdoc/core/classes/Functor.html +12 -12
- data/doc/rdoc/core/classes/Hash.html +447 -263
- data/doc/rdoc/core/classes/Indexable.html +110 -110
- data/doc/rdoc/core/classes/Integer.html +2 -2
- data/doc/rdoc/core/classes/Kernel.html +329 -329
- data/doc/rdoc/core/classes/Lazy/Promise.html +1 -1
- data/doc/rdoc/core/classes/MatchData.html +15 -15
- data/doc/rdoc/core/classes/Module.html +176 -157
- data/doc/rdoc/core/classes/NilClass.html +23 -23
- data/doc/rdoc/core/classes/Numeric.html +27 -27
- data/doc/rdoc/core/classes/Object.html +8 -8
- data/doc/rdoc/core/classes/ObjectSpace.html +5 -5
- data/doc/rdoc/core/classes/Proc.html +22 -22
- data/doc/rdoc/core/classes/Regexp.html +1 -1
- data/doc/rdoc/core/classes/Stackable.html +31 -31
- data/doc/rdoc/core/classes/String.html +332 -291
- data/doc/rdoc/core/classes/Symbol.html +1 -1
- data/doc/rdoc/core/classes/TrueClass.html +8 -8
- data/doc/rdoc/core/classes/UnboundMethod.html +18 -13
- data/doc/rdoc/core/created.rid +1 -1
- data/doc/rdoc/core/files/README.html +7 -29
- data/doc/rdoc/core/files/lib/core/facets/array/product_rb.html +1 -1
- data/doc/rdoc/core/files/lib/core/facets/enumerable/collect_rb.html +10 -1
- data/doc/rdoc/core/files/lib/core/facets/enumerable/compact_map_rb.html +92 -0
- data/doc/rdoc/core/files/lib/core/facets/enumerable/map_with_index_rb.html +92 -0
- data/doc/rdoc/core/files/lib/core/facets/enumerable/split_rb.html +1 -1
- data/doc/rdoc/core/files/lib/core/facets/hash/collate_rb.html +1 -1
- data/doc/rdoc/core/files/lib/core/facets/hash/group_by_value_rb.html +92 -0
- data/doc/rdoc/core/files/lib/core/facets/hash/new_with_rb.html +92 -0
- data/doc/rdoc/core/files/lib/core/facets/module/conflict_rb.html +1 -1
- data/doc/rdoc/core/files/lib/core/facets/module/extend_rb.html +92 -0
- data/doc/rdoc/core/files/lib/core/facets/string/align_rb.html +1 -1
- data/doc/rdoc/core/files/lib/core/facets/string/file_rb.html +96 -0
- data/doc/rdoc/core/files/lib/core/facets/string/xor_rb.html +1 -1
- data/doc/rdoc/core/files/lib/core/facets/to_hash_rb.html +5 -1
- data/doc/rdoc/core/files/lib/core/facets/unboundmethod/name_rb.html +1 -1
- data/doc/rdoc/core/fr_class_index.html +2 -0
- data/doc/rdoc/core/fr_file_index.html +6 -0
- data/doc/rdoc/core/fr_method_index.html +386 -373
- data/doc/rdoc/lore/classes/OpenStruct.html +6 -4
- data/doc/rdoc/lore/created.rid +1 -1
- data/doc/rdoc/lore/files/README.html +7 -29
- data/doc/rdoc/lore/files/lib/lore/facets/ostruct_rb.html +1 -1
- data/doc/rdoc/more/classes/ANSICode.html +66 -66
- data/doc/rdoc/more/classes/Advisable.html +37 -37
- data/doc/rdoc/more/classes/Advisable/Method.html +20 -20
- data/doc/rdoc/more/classes/Archive/Tar/Minitar.html +27 -27
- data/doc/rdoc/more/classes/Archive/Tar/Minitar/Input.html +28 -28
- data/doc/rdoc/more/classes/Archive/Tar/Minitar/Output.html +19 -19
- data/doc/rdoc/more/classes/Archive/Tar/Minitar/Reader.html +31 -31
- data/doc/rdoc/more/classes/Archive/Tar/Minitar/Writer.html +33 -33
- data/doc/rdoc/more/classes/Association.html +67 -53
- data/doc/rdoc/more/classes/Association/Kernel.html +11 -12
- data/doc/rdoc/more/classes/BBCode.html +36 -36
- data/doc/rdoc/more/classes/BaseX.html +16 -16
- data/doc/rdoc/more/classes/BiCrypt.html +67 -67
- data/doc/rdoc/more/classes/BinReadable.html +85 -85
- data/doc/rdoc/more/classes/BinReadable/ByteOrder.html +25 -25
- data/doc/rdoc/more/classes/Binding.html +8 -8
- data/doc/rdoc/more/classes/Buildable.html +4 -4
- data/doc/rdoc/more/classes/Cloneable.html +4 -4
- data/doc/rdoc/more/classes/ConsoleUtils.html +18 -18
- data/doc/rdoc/more/classes/Crypt.html +16 -16
- data/doc/rdoc/more/classes/CssTree.html +8 -8
- data/doc/rdoc/more/classes/Dictionary.html +52 -45
- data/doc/rdoc/more/classes/Enumerable.html +50 -50
- data/doc/rdoc/more/classes/Enumerable/Elementor.html +16 -16
- data/doc/rdoc/more/classes/Enumerable/Enumerator.html +4 -4
- data/doc/rdoc/more/classes/Enumerable/Filterable.html +30 -30
- data/doc/rdoc/more/classes/EnumerablePass.html +15 -15
- data/doc/rdoc/more/classes/Equatable.html +16 -16
- data/doc/rdoc/more/classes/Expirable.html +17 -17
- data/doc/rdoc/more/classes/Fileable.html +14 -14
- data/doc/rdoc/more/classes/Fileable/DSL.html +41 -41
- data/doc/rdoc/more/classes/Hash2Xml.html +4 -4
- data/doc/rdoc/more/classes/Hook.html +162 -0
- data/doc/rdoc/more/classes/HtmlFilter.html +9 -9
- data/doc/rdoc/more/classes/Instantiable.html +9 -9
- data/doc/rdoc/more/classes/Instantize.html +8 -8
- data/doc/rdoc/more/classes/Interval.html +187 -187
- data/doc/rdoc/more/classes/It.html +12 -12
- data/doc/rdoc/more/classes/Matcher.html +38 -38
- data/doc/rdoc/more/classes/Matcher/MatchData.html +4 -4
- data/doc/rdoc/more/classes/Memoizer.html +21 -21
- data/doc/rdoc/more/classes/Multiton.html +12 -12
- data/doc/rdoc/more/classes/Multiton/MetaMethods.html +28 -28
- data/doc/rdoc/more/classes/Net/SMTP.html +8 -8
- data/doc/rdoc/more/classes/OpEsc.html +5 -5
- data/doc/rdoc/more/classes/OpenCascade.html +4 -4
- data/doc/rdoc/more/classes/OpenHash.html +9 -9
- data/doc/rdoc/more/classes/OpenStructable.html +36 -36
- data/doc/rdoc/more/classes/PQueue.html +84 -84
- data/doc/rdoc/more/classes/Paramix.html +16 -16
- data/doc/rdoc/more/classes/Paramix/Delegator.html +16 -16
- data/doc/rdoc/more/classes/RWDelegator.html +16 -16
- data/doc/rdoc/more/classes/Random.html +5 -5
- data/doc/rdoc/more/classes/Random/Array.html +37 -37
- data/doc/rdoc/more/classes/Random/Hash.html +52 -52
- data/doc/rdoc/more/classes/Random/Object.html +4 -4
- data/doc/rdoc/more/classes/Random/String.html +34 -34
- data/doc/rdoc/more/classes/Random/String/Self.html +9 -9
- data/doc/rdoc/more/classes/Registerable.html +13 -13
- data/doc/rdoc/more/classes/Stash.html +28 -28
- data/doc/rdoc/more/classes/String/Mask.html +72 -72
- data/doc/rdoc/more/classes/String/Words.html +31 -31
- data/doc/rdoc/more/classes/System.html +253 -253
- data/doc/rdoc/more/classes/Timer.html +48 -48
- data/doc/rdoc/more/classes/Timer/Dummy.html +9 -9
- data/doc/rdoc/more/classes/Tuple.html +170 -170
- data/doc/rdoc/more/classes/TypeCast/Class.html +4 -4
- data/doc/rdoc/more/classes/TypeCast/Object.html +4 -4
- data/doc/rdoc/more/classes/Uninheritable.html +6 -6
- data/doc/rdoc/more/classes/X.html +117 -0
- data/doc/rdoc/more/classes/XOXO.html +11 -11
- data/doc/rdoc/more/classes/ZipUtils.html +88 -88
- data/doc/rdoc/more/classes/ZipUtils/DryRun.html +68 -68
- data/doc/rdoc/more/classes/ZipUtils/NoWrite.html +68 -68
- data/doc/rdoc/more/classes/ZipUtils/Verbose.html +60 -60
- data/doc/rdoc/more/created.rid +1 -1
- data/doc/rdoc/more/files/README.html +7 -29
- data/doc/rdoc/more/files/lib/more/facets/association_rb.html +1 -1
- data/doc/rdoc/more/files/lib/more/facets/dictionary_rb.html +1 -1
- data/doc/rdoc/more/files/lib/more/facets/hook_rb.html +96 -0
- data/doc/rdoc/more/files/lib/more/facets/paramix_rb.html +1 -1
- data/doc/rdoc/more/files/lib/more/facets/xoxo_rb.html +2 -2
- data/doc/rdoc/more/fr_class_index.html +2 -0
- data/doc/rdoc/more/fr_file_index.html +1 -0
- data/doc/rdoc/more/fr_method_index.html +686 -681
- data/lib/core/facets/array/product.rb +6 -23
- data/lib/core/facets/enumerable/collect.rb +3 -53
- data/lib/core/facets/enumerable/compact_map.rb +35 -0
- data/lib/core/facets/enumerable/map_with_index.rb +23 -0
- data/lib/core/facets/enumerable/split.rb +3 -3
- data/lib/core/facets/hash/collate.rb +45 -14
- data/lib/core/facets/hash/group_by_value.rb +65 -0
- data/lib/core/facets/hash/new_with.rb +15 -0
- data/lib/core/facets/module/extend.rb +11 -0
- data/lib/core/facets/string/align.rb +19 -18
- data/lib/core/facets/string/file.rb +17 -0
- data/lib/core/facets/string/xor.rb +9 -3
- data/lib/core/facets/to_hash.rb +274 -17
- data/lib/core/facets/unboundmethod/name.rb +4 -2
- data/lib/lore/facets/ostruct.rb +3 -0
- data/lib/more/facets/association.rb +28 -12
- data/lib/more/facets/dictionary.rb +10 -4
- data/lib/more/facets/hook.rb +65 -0
- data/lib/more/facets/paramix.rb +5 -5
- data/meta/abstract +13 -0
- data/meta/authors +1 -0
- data/meta/contact +1 -0
- data/meta/contributors +48 -0
- data/meta/created +1 -0
- data/meta/homepage +1 -0
- data/meta/license +1 -0
- data/meta/loadpath +3 -0
- data/meta/releases +14 -0
- data/meta/slogan +1 -0
- data/meta/summary +1 -0
- data/task/test.rake +116 -18
- data/test/core/array/test_product.rb +0 -6
- data/test/core/binding/test_local_variables.rb +9 -3
- data/test/core/enumerable/test_split.rb +19 -0
- data/test/core/module/test_conflict.rb +8 -3
- data/test/core/test_to_hash.rb +152 -0
- data/test/core/unboundmethod/test_arguments.rb +1 -1
- data/test/core/unboundmethod/test_name.rb +2 -2
- metadata +39 -8
- data/doc/log/bstats/stats.html +0 -39
- data/doc/log/stats.html +0 -25
- data/test/more/test_to_hash.rb +0 -58
@@ -1,24 +1,16 @@
|
|
1
|
-
|
1
|
+
class Array
|
2
2
|
|
3
|
-
|
3
|
+
if RUBY_VERSION < '1.9'
|
4
4
|
|
5
|
-
# Provides the
|
6
|
-
# This is the class-level method. The instance method
|
7
|
-
# calls on this.
|
8
|
-
#
|
9
|
-
# Enumerable.cartesian_product([1,2], [4], ["apple", "banana"])
|
10
|
-
# #=> [[1, 4, "apple"], [1, 4, "banana"], [2, 4, "apple"], [2, 4, "banana"]]
|
11
|
-
#
|
12
|
-
# Enumerable.cartesian_product([1,2], [3,4])
|
13
|
-
# #=> [[1, 3], [1, 4], [2, 3], [2, 4]]
|
5
|
+
# Provides the cartesian product of two or more arrays.
|
14
6
|
#
|
15
7
|
# a = []
|
16
|
-
# [1,2].
|
8
|
+
# [1,2].product([4,5])
|
17
9
|
# a #=> [[1, 4],[1, 5],[2, 4],[2, 5]]
|
18
10
|
#
|
19
11
|
# CREDIT: Thomas Hafner
|
20
12
|
|
21
|
-
def product(*enums
|
13
|
+
def product(*enums)
|
22
14
|
enums.unshift self
|
23
15
|
result = [[]]
|
24
16
|
while [] != enums
|
@@ -30,20 +22,11 @@ unless (RUBY_VERSION[0,3] == '1.9')
|
|
30
22
|
end
|
31
23
|
end
|
32
24
|
end
|
33
|
-
|
34
|
-
result.each{ |e| block.call(e) }
|
35
|
-
else
|
36
|
-
result
|
37
|
-
end
|
25
|
+
result
|
38
26
|
end
|
39
27
|
|
40
28
|
end
|
41
29
|
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
class Array
|
46
|
-
|
47
30
|
# Operator alias for cross-product.
|
48
31
|
#
|
49
32
|
# a = [1,2] ** [4,5]
|
@@ -1,54 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
#
|
5
|
-
# a = [1,2,3].collect_with_index { |e,i| e*i }
|
6
|
-
# a #=> [0,2,6]
|
7
|
-
#
|
8
|
-
# CREDIT: Gavin Sinclair
|
9
|
-
|
10
|
-
def collect_with_index
|
11
|
-
r = []
|
12
|
-
each_index do |i|
|
13
|
-
r << yield(self[i], i)
|
14
|
-
end
|
15
|
-
r
|
16
|
-
end
|
17
|
-
|
18
|
-
# Alias for collect_with_index.
|
19
|
-
|
20
|
-
alias_method :map_with_index, :collect_with_index
|
21
|
-
|
22
|
-
# A more versitle #compact method. It can be used to
|
23
|
-
# collect and filter items out in one single step.
|
24
|
-
#
|
25
|
-
# [1,2,3].compact_map do |n|
|
26
|
-
# n < 1 ? nil : n
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
# _produces_
|
30
|
-
#
|
31
|
-
# [2,3]
|
32
|
-
#
|
33
|
-
# NOTE: Perhaps nicer to have as added functionality for #compact.
|
34
|
-
#
|
35
|
-
# CREDIT: Trans
|
36
|
-
|
37
|
-
def compact_map(trash=nil, &block)
|
38
|
-
y = []
|
39
|
-
if block_given?
|
40
|
-
each do |*a|
|
41
|
-
r = yield(*a)
|
42
|
-
y << r unless trash == r
|
43
|
-
end
|
44
|
-
else
|
45
|
-
each do |r|
|
46
|
-
y << r unless trash == r
|
47
|
-
end
|
48
|
-
end
|
49
|
-
y
|
50
|
-
end
|
51
|
-
|
52
|
-
alias_method :compact_collect, :compact_map
|
53
|
-
end
|
1
|
+
# to be deprecated
|
2
|
+
require 'facets/enumerable/map_with_index'
|
3
|
+
require 'facets/enumerable/compact_map'
|
54
4
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Enumerable
|
2
|
+
|
3
|
+
# A more versitle #compact method. It can be used to
|
4
|
+
# collect and filter items out in one single step.
|
5
|
+
#
|
6
|
+
# [1,2,3].compact_map do |n|
|
7
|
+
# n < 1 ? nil : n
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# _produces_
|
11
|
+
#
|
12
|
+
# [2,3]
|
13
|
+
#
|
14
|
+
# NOTE: Perhaps nicer to have as added functionality for #compact.
|
15
|
+
#
|
16
|
+
# CREDIT: Trans
|
17
|
+
|
18
|
+
def compact_map(trash=nil, &block)
|
19
|
+
y = []
|
20
|
+
if block_given?
|
21
|
+
each do |*a|
|
22
|
+
r = yield(*a)
|
23
|
+
y << r unless trash == r
|
24
|
+
end
|
25
|
+
else
|
26
|
+
each do |r|
|
27
|
+
y << r unless trash == r
|
28
|
+
end
|
29
|
+
end
|
30
|
+
y
|
31
|
+
end
|
32
|
+
|
33
|
+
alias_method :compact_collect, :compact_map
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Enumerable
|
2
|
+
|
3
|
+
# Same as #collect but with an iteration counter.
|
4
|
+
#
|
5
|
+
# a = [1,2,3].collect_with_index { |e,i| e*i }
|
6
|
+
# a #=> [0,2,6]
|
7
|
+
#
|
8
|
+
# CREDIT: Gavin Sinclair
|
9
|
+
|
10
|
+
def map_with_index
|
11
|
+
r = []
|
12
|
+
each_index do |i|
|
13
|
+
r << yield(self[i], i)
|
14
|
+
end
|
15
|
+
r
|
16
|
+
end
|
17
|
+
|
18
|
+
# Alias for map_with_index.
|
19
|
+
|
20
|
+
alias_method :collect_with_index, :map_with_index
|
21
|
+
|
22
|
+
end
|
23
|
+
|
@@ -8,8 +8,8 @@ module Enumerable
|
|
8
8
|
# CREDIT: Trans
|
9
9
|
|
10
10
|
def split(pattern)
|
11
|
-
sect = []
|
12
11
|
memo = []
|
12
|
+
sect = []
|
13
13
|
each do |obj|
|
14
14
|
if pattern === obj
|
15
15
|
memo << sect
|
@@ -18,8 +18,8 @@ module Enumerable
|
|
18
18
|
sect << obj
|
19
19
|
end
|
20
20
|
end
|
21
|
-
memo << sect
|
22
|
-
memo.pop while memo.last
|
21
|
+
memo << sect
|
22
|
+
memo.pop while memo.last == []
|
23
23
|
memo
|
24
24
|
end
|
25
25
|
|
@@ -6,40 +6,71 @@ class Hash
|
|
6
6
|
# { :a=>1, :b=>2 }.collate :a=>3, :b=>4, :c=>5
|
7
7
|
# #=> { :a=>[1,3], :b=>[2,4], :c=>[5] }
|
8
8
|
#
|
9
|
+
# CREDIT: Tilo Sloboda
|
9
10
|
# CREDIT: Gavin Kistner (Phrogz)
|
10
11
|
|
11
12
|
def collate(other_hash)
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
# The same as #collate, but modifies the receiver in place.
|
16
|
-
|
17
|
-
def collate!(other_hash)
|
13
|
+
h = Hash.new
|
18
14
|
# Prepare, ensuring every existing key is already an Array
|
19
15
|
each do |key, value|
|
20
16
|
if value.is_a?(Array)
|
21
|
-
|
17
|
+
h[key] = value
|
22
18
|
else
|
23
|
-
|
19
|
+
h[key] = [value]
|
24
20
|
end
|
25
21
|
end
|
26
22
|
# Collate with values from other_hash
|
27
23
|
other_hash.each do |key, value|
|
28
|
-
if
|
24
|
+
if h[key]
|
29
25
|
if value.is_a?(Array)
|
30
|
-
|
26
|
+
h[key].concat(value)
|
31
27
|
else
|
32
|
-
|
28
|
+
h[key] << value
|
33
29
|
end
|
34
30
|
elsif value.is_a?(Array)
|
35
|
-
|
31
|
+
h[key] = value
|
36
32
|
else
|
37
|
-
|
33
|
+
h[key] = [value]
|
38
34
|
end
|
39
35
|
end
|
40
36
|
#each{ |key, value| value.uniq! } if options[ :uniq ]
|
41
|
-
|
37
|
+
h
|
42
38
|
end
|
43
39
|
|
40
|
+
# The same as #collate, but modifies the receiver in place.
|
41
|
+
|
42
|
+
def collate!(other_hash)
|
43
|
+
result = self.collate(other_hash)
|
44
|
+
self.replace(result)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Old version.
|
48
|
+
#def collate!(other_hash)
|
49
|
+
# # Prepare, ensuring every existing key is already an Array
|
50
|
+
# each do |key, value|
|
51
|
+
# if value.is_a?(Array)
|
52
|
+
# self[key] = value
|
53
|
+
# else
|
54
|
+
# self[key] = [value]
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# # Collate with values from other_hash
|
58
|
+
# other_hash.each do |key, value|
|
59
|
+
# if self[key]
|
60
|
+
# if value.is_a?(Array)
|
61
|
+
# self[key].concat( value )
|
62
|
+
# else
|
63
|
+
# self[key] << value
|
64
|
+
# end
|
65
|
+
# elsif value.is_a?(Array)
|
66
|
+
# self[key] = value
|
67
|
+
# else
|
68
|
+
# self[key] = [value]
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
# #each{ |key, value| value.uniq! } if options[ :uniq ]
|
72
|
+
# self
|
73
|
+
#end
|
74
|
+
|
44
75
|
end
|
45
76
|
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
# Like group_by, but allows hash values to be grouped with weeding out the keys.
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
#
|
7
|
+
# birthdays = {...} # Maps each person to his/her birthday.
|
8
|
+
#
|
9
|
+
# Now I want to have the list of people that have their birthday
|
10
|
+
# on a specific date. This can be done by creating a hash first,
|
11
|
+
# using group_by:
|
12
|
+
#
|
13
|
+
# birthdays.group_by{|person, birthday| birthday}
|
14
|
+
#
|
15
|
+
# This returns:
|
16
|
+
#
|
17
|
+
# {date=>[[person1, date], [person2, date], [person3, date]]}
|
18
|
+
#
|
19
|
+
# ... which is a bit inconvient. Too many dates. I would rather
|
20
|
+
# like to have:
|
21
|
+
#
|
22
|
+
# {date=>[person1, person2, person3]]}
|
23
|
+
#
|
24
|
+
# This can be achieved by:
|
25
|
+
#
|
26
|
+
# birthdays.inject!({}){|h, (person, date)| (h[date] ||= []) << person}
|
27
|
+
#
|
28
|
+
# I've used this pattern just once too often, so I moved the code
|
29
|
+
# to Hash (and Enumerable, for associative arrays). Here's the
|
30
|
+
# cleaner code:
|
31
|
+
#
|
32
|
+
# birthdays.group_by_value
|
33
|
+
#
|
34
|
+
# h = {"A"=>1, "B"=>1, "C"=>1, "D"=>2, "E"=>2, "F"=>2, "G"=>3, "H"=>3, "I"=>3}
|
35
|
+
#
|
36
|
+
# h.group_by{|k, v| v} # ==> {1=>[["A", 1], ["B", 1], ["C", 1]], 2=>[["D", 2], ["E", 2], ["F", 2]], 3=>[["G", 3], ["H", 3], ["I", 3]]}
|
37
|
+
# h.group_by_value # ==> {1=>["A", "B", "C"], 2=>["D", "E", "F"], 3=>["G", "H", "I"]}
|
38
|
+
# h.sort.group_by_value # ==> [[1, ["A", "B", "C"]], [2, ["D", "E", "F"]], [3, ["G", "H", "I"]]]
|
39
|
+
#
|
40
|
+
# CREDIT: Erik Veenstra
|
41
|
+
|
42
|
+
def group_by_value
|
43
|
+
res = {}
|
44
|
+
each{|k, v| (res[v] ||= []) << k}
|
45
|
+
res
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
# Not sure this is a good idea for enumerable.
|
52
|
+
#
|
53
|
+
#module Enumerable
|
54
|
+
#
|
55
|
+
# # For associative arrays, like the result of Hash#sort.
|
56
|
+
# #
|
57
|
+
# def group_by_value
|
58
|
+
# kv = k = v = nil
|
59
|
+
# res = []
|
60
|
+
# each{|k, v| (res.assoc(v) || (res << kv=[v, []]; kv)).last << k}
|
61
|
+
# res
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
#end
|
65
|
+
|
@@ -14,8 +14,9 @@ class String
|
|
14
14
|
end
|
15
15
|
|
16
16
|
# Align a string to the right.
|
17
|
-
#
|
18
|
-
#
|
17
|
+
#
|
18
|
+
# The default alignment separation is a new line ("\n").
|
19
|
+
# This can be changed as can be the padding string which
|
19
20
|
# defaults to a single space (' ').
|
20
21
|
#
|
21
22
|
# s = <<-EOS
|
@@ -24,28 +25,28 @@ class String
|
|
24
25
|
# so on
|
25
26
|
# EOS
|
26
27
|
#
|
27
|
-
# puts s.align_right(
|
28
|
+
# puts s.align_right(14)
|
28
29
|
#
|
29
30
|
# _produces_
|
30
31
|
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
32
|
+
# This is a test
|
33
|
+
# and
|
34
|
+
# so on
|
34
35
|
#
|
35
36
|
# CREDIT: Trans
|
36
37
|
|
37
38
|
def align_right(n, sep="\n", c=' ')
|
38
39
|
return rjust(n.to_i,c.to_s) if sep==nil
|
39
|
-
q = split(sep.to_s).
|
40
|
+
q = split(sep.to_s).map do |line|
|
40
41
|
line.rjust(n.to_i,c.to_s)
|
41
|
-
|
42
|
+
end
|
42
43
|
q.join(sep.to_s)
|
43
44
|
end
|
44
45
|
|
45
46
|
# Align a string to the left.
|
46
47
|
#
|
47
|
-
# The
|
48
|
-
# This can be
|
48
|
+
# The default alignment separation is a new line ("\n").
|
49
|
+
# This can be changed as can be the padding string which
|
49
50
|
# defaults to a single space (' ').
|
50
51
|
#
|
51
52
|
# s = <<-EOS
|
@@ -54,27 +55,27 @@ class String
|
|
54
55
|
# so on
|
55
56
|
# EOS
|
56
57
|
#
|
57
|
-
# puts s.align_left(
|
58
|
+
# puts s.align_left(20, "\n", '.')
|
58
59
|
#
|
59
60
|
# _produces_
|
60
61
|
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
62
|
+
# This is a test......
|
63
|
+
# and.................
|
64
|
+
# so on...............
|
64
65
|
#
|
65
66
|
# CREDIT: Trans
|
66
67
|
|
67
68
|
def align_left(n, sep="\n", c=' ')
|
68
69
|
return ljust(n.to_i,c.to_s) if sep==nil
|
69
|
-
q = split(sep.to_s).
|
70
|
-
line.ljust(n.to_i,c.to_s)
|
71
|
-
|
70
|
+
q = split(sep.to_s).map do |line|
|
71
|
+
line.strip.ljust(n.to_i,c.to_s)
|
72
|
+
end
|
72
73
|
q.join(sep.to_s)
|
73
74
|
end
|
74
75
|
|
75
76
|
# Centers each line of a string.
|
76
77
|
#
|
77
|
-
# The
|
78
|
+
# The default alignment separation is a new line ("\n").
|
78
79
|
# This can be changed as can be the padding string which
|
79
80
|
# defaults to a single space (' ').
|
80
81
|
#
|