facets 2.5.0 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
#
|