class MARCSpec::MultiValueMap
A MultiValueMap
(in this conectex) is an array of duples of the form
- thingToMatch, 'Value'
-
(or [thingToMatch, [array,of,values]])
along with an associated name.
Accessing via [] will give you an array of non-nil values that match (via ===) the corresponding keys.
Keys can be either strings or regular expressions (e.g., /^Bil/).
IF the key is a regexp, the value may then be a Proc object that takes a single argument: the MatchData object produced by calling key.match(passed_in_value)
Again, note that if several keys are === to the passed argument, all the values will be returned.
Public Class Methods
Try to produce a valid MVMap from a solrmarc file @param [String] filename The file to read @return [MARCSpec::MultiValueMap] A new mvmap
# File lib/marcspec/multivaluemap.rb, line 86 def self.from_solrmarc_file filename mapname = File.basename(filename).sub(/\..+?$/, '') kvlist = [] File.open(filename) do |f| prop = Java::java.util.Properties.new prop.load(f.to_inputstream) prop.each do |patstring,kv| unless patstring =~ /^pattern/ and kv =~ /.+=>.+/ log.warn "MultiValueMap import skipping weird line in #{filename}\n #{l}" next end match = /^\s*(.+?)\s*=>\s*(.+?)\s*$/.match(kv) kvlist << [Regexp.new(match[1]), match[2]] end end rv = self.new(nil,nil) # empty; avoid the optimize rv.mapname = mapname rv.map = kvlist return rv end
Override initialize and map= so we can do some optimization
MARCSpec::Map::new
# File lib/marcspec/multivaluemap.rb, line 25 def initialize *args super(*args) self.optimize if @map and @mapname end
Public Instance Methods
Given a passed_in_key (and optional default) return the set of values that match, as described above.
# File lib/marcspec/multivaluemap.rb, line 54 def [] key, default=nil rv = [] self.optimize unless @super_regexp if @super_regexp.match key # do *any* of them match? @map.each do |pv| if pv[1].is_a? Proc match = pv[0].match key rv << pv[1].call(match) if match else rv << pv[1] if pv[0] === key end end rv.flatten! rv.compact! rv.uniq! end if rv.size > 0 return rv else if default == :passthrough return key else return default end end end
Produce a string suitable for pretty-printing. Unfortunately, we need to just plain delete the procs before doing so
# File lib/marcspec/multivaluemap.rb, line 110 def asPPString map = @map.reject {|kv| kv[1].is_a? Proc} s = StringIO.new s.print "{\n :maptype=>:multi,\n :mapname=>" PP.singleline_pp(@mapname, s) s.print ",\n :map => " PP.pp(map, s) s.puts "\n}" return s.string end
# File lib/marcspec/multivaluemap.rb, line 30 def map= map @map = map end
# File lib/marcspec/multivaluemap.rb, line 35 def optimize @super_regexp = Regexp.union @map.map{|pv| pv[0]} inverted = {} @map.each do |pv| inverted[pv[1]] ||= [] inverted[pv[1]] << pv[0] end inverted.each_pair do |vals, patterns| next unless patterns.size > 1 newpat = Regexp.union patterns patterns.each do |p| @map.delete_if{|pv| p == pv[0]} end @map << [newpat, vals] end end