Class: RDF::Query::Solutions
- Inherits:
-
Array
- Object
- Array
- RDF::Query::Solutions
- Defined in:
- lib/rdf/query/solutions.rb
Overview
An RDF basic graph pattern (BGP) query solution sequence.
Instance Method Summary collapse
-
#bindings ⇒ Hash{Symbol => Array<RDF::Term>}
Returns hash of bindings from each solution.
-
#count(&block) ⇒ Integer
Returns the number of matching query solutions.
-
#distinct ⇒ self
(also: #distinct!, #reduced, #reduced!)
Ensures that the solutions in this solution sequence are unique.
-
#dup ⇒ RDF::Query::Solutions
Duplicates each solution.
-
#filter(criteria = {}) {|solution| ... } ⇒ self
(also: #filter!)
Filters this solution sequence by the given
criteria. -
#have_variables?(variables) ⇒ Boolean
(also: #has_variables?)
Returns
trueif this solution sequence contains bindings for any of the givenvariables. -
#limit(length) ⇒ self
(also: #limit!)
Limits the number of solutions in this solution sequence to a maximum of
length. -
#merge(other) ⇒ RDF::Query::Solutions
Merge solutions in
otherinto a new solutions instance. -
#minus(other) ⇒ RDF::Query::Solutions
Difference between solution sets, from SPARQL 1.1.
-
#offset(start) ⇒ self
(also: #offset!)
Limits this solution sequence to bindings starting from the
startoffset in the overall solution sequence. -
#order(*variables) {|solution| ... } ⇒ self
(also: #order_by)
Reorders this solution sequence by the given
variables. -
#project(*variables) ⇒ self
(also: #select)
Restricts this solution sequence to the given
variablesonly. -
#variable_names ⇒ Array<Symbol>
Returns an array of the distinct variable names used in this solution sequence.
Instance Method Details
#bindings ⇒ Hash{Symbol => Array<RDF::Term>}
Returns hash of bindings from each solution. Each bound variable will have an array of bound values representing those from each solution, where a given solution will have just a single value for each bound variable
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/rdf/query/solutions.rb', line 99 def bindings bindings = {} each do |solution| solution.each do |key, value| bindings[key] ||= [] bindings[key] << value end end bindings end |
#count ⇒ Integer #count({ |solution| ... }) {|solution| ... } ⇒ Integer
Returns the number of matching query solutions.
59 60 61 |
# File 'lib/rdf/query/solutions.rb', line 59 def count(&block) super end |
#distinct ⇒ self Also known as: distinct!, reduced, reduced!
Ensures that the solutions in this solution sequence are unique.
244 245 246 247 |
# File 'lib/rdf/query/solutions.rb', line 244 def distinct self.uniq! self end |
#dup ⇒ RDF::Query::Solutions
Duplicates each solution.
113 114 115 |
# File 'lib/rdf/query/solutions.rb', line 113 def dup RDF::Query::Solutions.new(self.compact.map(&:dup)) end |
#filter(criteria = {}) {|solution| ... } ⇒ self Also known as: filter!
Filters this solution sequence by the given criteria.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/rdf/query/solutions.rb', line 140 def filter(criteria = {}) @variable_names = nil if block_given? self.reject! do |solution| !yield(solution.is_a?(Solution) ? solution : Solution.new(solution)) end else self.reject! do |solution| solution = solution.is_a?(Solution) ? solution : Solution.new(solution) results = criteria.map do |name, value| case value when Array then value.any? {|v| solution[name] == v} when Regexp then solution[name].to_s.match(value) else solution[name] == value end end !results.all? end end self end |
#have_variables?(variables) ⇒ Boolean Also known as: has_variables?
Returns true if this solution sequence contains bindings for any of the given variables.
89 90 91 |
# File 'lib/rdf/query/solutions.rb', line 89 def have_variables?(variables) self.any? { |solution| solution.has_variables?(variables) } end |
#limit(length) ⇒ self Also known as: limit!
Limits the number of solutions in this solution sequence to a maximum of length.
276 277 278 279 280 281 282 283 284 |
# File 'lib/rdf/query/solutions.rb', line 276 def limit(length) length = length.to_i raise ArgumentError, "expected zero or a positive integer, got #{length}" if length < 0 case length when 0 then self.clear else self.slice!(length..-1) if length < self.size end self end |
#merge(other) ⇒ RDF::Query::Solutions
Merge solutions in other into a new solutions instance. Each solution in other is merged into those solutions in self that are compatible.
122 123 124 125 126 127 128 129 130 |
# File 'lib/rdf/query/solutions.rb', line 122 def merge(other) other ||= RDF::Query::Solutions() return other if self.empty? return self if other.empty? RDF::Query::Solutions(self.map do |s1| other.map { |s2| s2.merge(s1) if s2.compatible?(s1) } end.flatten.compact) end |
#minus(other) ⇒ RDF::Query::Solutions
Difference between solution sets, from SPARQL 1.1.
The minus operation on solutions returns those solutions which either have no compatible solution in other, or the solution domains are disjoint.
171 172 173 174 175 |
# File 'lib/rdf/query/solutions.rb', line 171 def minus(other) self.dup.filter! do |soln| !other.any? {|soln2| soln.compatible?(soln2) && !soln.disjoint?(soln2)} end end |
#offset(start) ⇒ self Also known as: offset!
Limits this solution sequence to bindings starting from the start offset in the overall solution sequence.
259 260 261 262 263 264 265 |
# File 'lib/rdf/query/solutions.rb', line 259 def offset(start) case start = start.to_i when 0 then nil else self.slice!(0...start) end self end |
#order(*variables) {|solution| ... } ⇒ self Also known as: order_by
Reorders this solution sequence by the given variables.
Variables may be symbols or Variable instances. A variable may also be a Procedure/Lambda, compatible with ‘::Enumerable#sort`. This takes two arguments (solutions) and returns -1, 0, or 1 equivalently to <=>.
If called with a block, variables are ignored, and the block is invoked with pairs of solutions. The block is expected to return -1, 0, or 1 equivalently to <=>.
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/rdf/query/solutions.rb', line 193 def order(*variables) if variables.empty? && !block_given? raise ArgumentError, "wrong number of arguments (0 for 1)" else self.sort! do |a, b| if block_given? yield((a.is_a?(Solution) ? a : Solution.new(a)), (b.is_a?(Solution) ? b : Solution.new(b))) else # Try each variable until a difference is found. variables.inject(nil) do |memo, v| memo || begin comp = v.is_a?(Proc) ? v.call(a, b) : (v = v.to_sym; a[v] <=> b[v]) comp == 0 ? false : comp end end || 0 end end end self end |
#project(*variables) ⇒ self Also known as: select
Restricts this solution sequence to the given variables only.
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/rdf/query/solutions.rb', line 220 def project(*variables) if variables.empty? raise ArgumentError, "wrong number of arguments (0 for 1)" else variables.map!(&:to_sym) self.each do |solution| solution.bindings.delete_if { |k, v| !variables.include?(k.to_sym) } end end # Make sure variable_names are ordered by projected variables projected_vars, vars = variables.map(&:to_sym), variable_names vars = variable_names # Maintain projected order, and add any non-projected variables @variable_names = (projected_vars & vars) + (vars - projected_vars) self end |
#variable_names ⇒ Array<Symbol>
Returns an array of the distinct variable names used in this solution sequence.
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/rdf/query/solutions.rb', line 68 def variable_names @variable_names ||= begin variables = self.inject({}) do |result, solution| solution.each_name do |name| result[name] ||= true end result end variables.keys end end |