liqrrdmetal 0.5 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/liqrrdmetal/liqrrdmetal.rb +48 -3
- metadata +1 -1
@@ -80,7 +80,7 @@ require 'strscan'
|
|
80
80
|
#
|
81
81
|
# Copyright (c) 2011, Gavin Kistner (!@phrogz.net)
|
82
82
|
module LiqrrdMetal
|
83
|
-
VERSION = 0.5
|
83
|
+
VERSION = "0.5.1"
|
84
84
|
|
85
85
|
# If you want score_with_parts to be accurate, the MATCH score must be unique
|
86
86
|
MATCH = 0.00 #:nodoc:
|
@@ -129,9 +129,52 @@ module LiqrrdMetal
|
|
129
129
|
def to_json(*a); { t:@text, m:!!@match }.to_json(*a); end
|
130
130
|
end
|
131
131
|
|
132
|
+
# Mixed into results for results_by_score
|
133
|
+
module MatchResult
|
134
|
+
# The text used to match against
|
135
|
+
attr_accessor :liqrrd_match
|
136
|
+
|
137
|
+
# The score for this result
|
138
|
+
attr_accessor :liqrrd_score
|
139
|
+
|
140
|
+
# Array of MatchPart instances
|
141
|
+
attr_accessor :liqrrd_parts
|
142
|
+
end
|
143
|
+
|
132
144
|
module_function
|
133
145
|
|
134
|
-
# Match a single search term
|
146
|
+
# Match a single search term against an array of objects,
|
147
|
+
# using the supplied block to find the string to match against,
|
148
|
+
# receiving an array of your objects with the MatchResult module mixed in.
|
149
|
+
#
|
150
|
+
# User = Struct.new :name, :email, :id
|
151
|
+
# users = [ User.new( "Gavin Kistner", "!@phrogz.net", 42 ),
|
152
|
+
# User.new( "David Letterman", "lateshow@pipeline.com", 17 ),
|
153
|
+
# User.new( "Scott Adams", "scottadams@aol.com", 82 ) ]
|
154
|
+
#
|
155
|
+
# scom = LiqrrdMetal.results_by_score( "s.com", users ){ |user| user.email }
|
156
|
+
# #=> [#<struct User name="Scott Adams", email="scottadams@aol.com", id=82>,
|
157
|
+
# #=> #<struct User name="David Letterman", email="lateshow@pipeline.com", id=17>]
|
158
|
+
#
|
159
|
+
# p scom.map{ |user| user.liqrrd_score }
|
160
|
+
# #=> [0.7222222222222222, 0.7619047619047619]
|
161
|
+
#
|
162
|
+
# p scom.map{ |user| user.liqrrd_parts.map(&:to_html).join }
|
163
|
+
# #=> ["<span class='match'>s</span>cottadams@aol<span class='match'>.com</span>",
|
164
|
+
# #=> "late<span class='match'>s</span>how@pipeline<span class='match'>.com</span>"]
|
165
|
+
def results_by_score( search, objects, score_threshold=1.0 )
|
166
|
+
objects.each{ |o|
|
167
|
+
o.extend MatchResult
|
168
|
+
o.liqrrd_match = yield(o)
|
169
|
+
o.liqrrd_score, o.liqrrd_parts = score_with_parts(search,o.liqrrd_match)
|
170
|
+
}.select{ |o|
|
171
|
+
o.liqrrd_score < score_threshold
|
172
|
+
}.sort_by{ |o|
|
173
|
+
[ o.liqrrd_score, o.liqrrd_match ]
|
174
|
+
}
|
175
|
+
end
|
176
|
+
|
177
|
+
# Match a single search term against an array of possible results,
|
135
178
|
# receiving an array sorted by score (descending) of the matched text parts.
|
136
179
|
# By default non-matching entries are not included in the results; set the
|
137
180
|
# `score_threshold` below 0.0 to include them.
|
@@ -210,7 +253,7 @@ module LiqrrdMetal
|
|
210
253
|
started = false
|
211
254
|
scanner = StringScanner.new actual
|
212
255
|
search.chars.each do |c|
|
213
|
-
return NO_MATCH unless fluff = scanner.scan_until(/#{c}/i)
|
256
|
+
return NO_MATCH unless fluff = scanner.scan_until(/#{Regexp.escape c}/i)
|
214
257
|
pos = scanner.pos-1
|
215
258
|
started = true if pos == 0
|
216
259
|
if /\s/ =~ actual[pos-1]
|
@@ -228,3 +271,5 @@ module LiqrrdMetal
|
|
228
271
|
scores
|
229
272
|
end
|
230
273
|
end
|
274
|
+
|
275
|
+
|