josh-multimap 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/fuzzy_nested_multimap.rb +51 -9
- data/lib/multimap.rb +7 -1
- data/lib/nested_multimap.rb +6 -5
- metadata +1 -1
@@ -3,7 +3,21 @@ require 'nested_multimap'
|
|
3
3
|
# FuzzyNestedMultimap is an extension on top of NestedMultimap
|
4
4
|
# that allows fuzzy matching.
|
5
5
|
class FuzzyNestedMultimap < NestedMultimap
|
6
|
-
|
6
|
+
def self.[](*args) #:nodoc:
|
7
|
+
map = super
|
8
|
+
map.instance_variable_set('@fuzz', {})
|
9
|
+
map
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(default = []) #:nodoc:
|
13
|
+
@fuzz = {}
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize_copy(original) #:nodoc:
|
18
|
+
@fuzz = original.instance_variable_get('@fuzz').dup
|
19
|
+
super
|
20
|
+
end
|
7
21
|
|
8
22
|
# call-seq:
|
9
23
|
# multimap[*keys] = value => value
|
@@ -16,18 +30,22 @@ class FuzzyNestedMultimap < NestedMultimap
|
|
16
30
|
def store(*args)
|
17
31
|
keys = args.dup
|
18
32
|
value = keys.pop
|
19
|
-
key = keys.shift
|
33
|
+
key = keys.shift
|
20
34
|
|
21
35
|
raise ArgumentError, 'wrong number of arguments (1 for 2)' unless value
|
22
36
|
|
23
|
-
|
24
|
-
|
37
|
+
unless key.respond_to?(:=~)
|
38
|
+
raise ArgumentError, "unsupported key: #{args.first.inspect}"
|
39
|
+
end
|
40
|
+
|
41
|
+
if key.is_a?(Regexp)
|
42
|
+
@fuzz[value] = key
|
25
43
|
if keys.empty?
|
26
|
-
hash_each_pair { |k, l| l << value if
|
44
|
+
hash_each_pair { |k, l| l << value if k =~ key }
|
27
45
|
self.default << value
|
28
46
|
else
|
29
47
|
hash_each_pair { |k, _|
|
30
|
-
if
|
48
|
+
if k =~ key
|
31
49
|
args[0] = k
|
32
50
|
super(*args)
|
33
51
|
end
|
@@ -36,11 +54,35 @@ class FuzzyNestedMultimap < NestedMultimap
|
|
36
54
|
self.default = self.class.new(default) unless default.is_a?(self.class)
|
37
55
|
default[*keys.dup] = value
|
38
56
|
end
|
39
|
-
when String
|
40
|
-
super(*args)
|
41
57
|
else
|
42
|
-
|
58
|
+
super(*args)
|
43
59
|
end
|
44
60
|
end
|
45
61
|
alias_method :[]=, :store
|
62
|
+
|
63
|
+
def freeze #:nodoc:
|
64
|
+
@fuzz.clear
|
65
|
+
@fuzz = nil
|
66
|
+
super
|
67
|
+
end
|
68
|
+
|
69
|
+
undef :index, :invert
|
70
|
+
|
71
|
+
protected
|
72
|
+
def update_container(key) #:nodoc:
|
73
|
+
super do |container|
|
74
|
+
if container.is_a?(self.class)
|
75
|
+
container.each_container_with_default do |c|
|
76
|
+
c.delete_if do |value|
|
77
|
+
(requirement = @fuzz[value]) && key !~ requirement
|
78
|
+
end
|
79
|
+
end
|
80
|
+
else
|
81
|
+
container.delete_if do |value|
|
82
|
+
(requirement = @fuzz[value]) && key !~ requirement
|
83
|
+
end
|
84
|
+
end
|
85
|
+
yield container
|
86
|
+
end
|
87
|
+
end
|
46
88
|
end
|
data/lib/multimap.rb
CHANGED
@@ -77,8 +77,14 @@ class Multimap < Hash
|
|
77
77
|
super
|
78
78
|
clear
|
79
79
|
original.each_pair { |key, container| self[key] = container }
|
80
|
+
self.default = original.default.dup
|
80
81
|
end
|
81
82
|
|
83
|
+
#--
|
84
|
+
# Setting a default proc is not supported
|
85
|
+
#++
|
86
|
+
undef :default_proc
|
87
|
+
|
82
88
|
# call-seq:
|
83
89
|
# map[key] = value => value
|
84
90
|
# map.store(key, value) => value
|
@@ -307,7 +313,7 @@ class Multimap < Hash
|
|
307
313
|
# map = Multimap["n" => 100, "m" => 100, "d" => [200, 300]]
|
308
314
|
# map.invert #=> Multimap[100 => ["n", "m"], 200 => "d", 300 => "d"]
|
309
315
|
def invert
|
310
|
-
h =
|
316
|
+
h = self.class.new(default.dup)
|
311
317
|
each_pair { |key, value| h[value] = key }
|
312
318
|
h
|
313
319
|
end
|
data/lib/nested_multimap.rb
CHANGED
@@ -16,20 +16,21 @@ class NestedMultimap < Multimap
|
|
16
16
|
# map["a"] = 102
|
17
17
|
# map #=> {"a"=>{"b"=>[100, 101, 102], default => [100, 102]}}
|
18
18
|
def store(*args)
|
19
|
-
value = args.pop
|
20
|
-
key = args.shift
|
21
19
|
keys = args
|
20
|
+
value = args.pop
|
22
21
|
|
23
22
|
raise ArgumentError, 'wrong number of arguments (1 for 2)' unless value
|
24
23
|
|
25
|
-
if keys.length >
|
26
|
-
update_container(
|
24
|
+
if keys.length > 1
|
25
|
+
update_container(keys.shift) do |container|
|
27
26
|
container = self.class.new(container) unless container.is_a?(self.class)
|
28
27
|
container[*keys] = value
|
29
28
|
container
|
30
29
|
end
|
30
|
+
elsif keys.length == 1
|
31
|
+
super(keys.first, value)
|
31
32
|
else
|
32
|
-
|
33
|
+
self << value
|
33
34
|
end
|
34
35
|
end
|
35
36
|
alias_method :[]=, :store
|