function closest_match
Recursively finds the closest matching specification from a list of specs by comparing hierarchical keys (type, group, label, overlay) with a target match pattern.
/tf/active/vicechatdev/patches/util.py
2230 - 2261
complex
Purpose
This function implements a hierarchical matching algorithm that finds the best matching specification from a list of candidates. It works by recursively comparing elements at each depth level, handling exact matches, string prefix matches, and numeric proximity matches. When exact matches exist at a level, it recurses deeper; otherwise, it returns the spec with the best partial match. This is typically used in visualization or styling systems where specifications need to be matched against hierarchical object properties.
Source Code
def closest_match(match, specs, depth=0):
"""
Recursively iterates over type, group, label and overlay key,
finding the closest matching spec.
"""
new_specs = []
match_lengths = []
for i, spec in specs:
if spec[0] == match[0]:
new_specs.append((i, spec[1:]))
else:
if all(isinstance(s[0], str) for s in [spec, match]):
match_length = max(i for i in range(len(match[0]))
if match[0].startswith(spec[0][:i]))
elif is_number(match[0]) and is_number(spec[0]):
m = bool(match[0]) if isinstance(match[0], np.bool_) else match[0]
s = bool(spec[0]) if isinstance(spec[0], np.bool_) else spec[0]
match_length = -abs(m-s)
else:
match_length = 0
match_lengths.append((i, match_length, spec[0]))
if len(new_specs) == 1:
return new_specs[0][0]
elif new_specs:
depth = depth+1
return closest_match(match[1:], new_specs, depth)
else:
if depth == 0 or not match_lengths:
return None
else:
return sorted(match_lengths, key=lambda x: -x[1])[0][0]
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
match |
- | - | positional_or_keyword |
specs |
- | - | positional_or_keyword |
depth |
- | 0 | positional_or_keyword |
Parameter Details
match: A sequence (tuple or list) representing the hierarchical keys to match against. Each element represents a level in the hierarchy (e.g., type, group, label, overlay key). Elements can be strings, numbers, or numpy boolean values.
specs: A list of tuples where each tuple contains (index, spec_sequence). The index is an identifier for the spec, and spec_sequence is a sequence of hierarchical keys similar to 'match'. This represents the candidate specifications to match against.
depth: Integer tracking the current recursion depth, starting at 0. Used internally to determine if the function should return None (at depth 0) or the best partial match (at deeper levels) when no exact matches are found.
Return Value
Returns an integer index identifying the closest matching spec from the input specs list. Returns None if no match is found at depth 0. The matching algorithm prioritizes exact matches, then string prefix matches (longest common prefix), then numeric proximity (smallest absolute difference). For boolean values, they are converted to regular booleans before comparison.
Dependencies
numpy
Required Imports
import numpy as np
Usage Example
import numpy as np
def is_number(val):
return isinstance(val, (int, float, np.number))
# Define specs with (index, spec_tuple) format
specs = [
(0, ('Scatter', 'Group1', 'label1')),
(1, ('Scatter', 'Group2', 'label2')),
(2, ('Line', 'Group1', 'label1'))
]
# Find closest match for a target pattern
match_pattern = ('Scatter', 'Group1', 'label1')
result = closest_match(match_pattern, specs)
print(f"Closest match index: {result}") # Output: 0
# Partial string match example
specs2 = [
(0, ('ScatterPlot', 'data')),
(1, ('LinePlot', 'data'))
]
match_pattern2 = ('Scatter', 'data')
result2 = closest_match(match_pattern2, specs2)
print(f"Partial match index: {result2}") # Output: 0
# Numeric match example
specs3 = [
(0, (1.0, 'value')),
(1, (5.0, 'value'))
]
match_pattern3 = (2.0, 'value')
result3 = closest_match(match_pattern3, specs3)
print(f"Numeric match index: {result3}") # Output: 0 (1.0 is closer to 2.0)
Best Practices
- Ensure the 'is_number' helper function is available in the scope before calling this function
- The 'match' and spec sequences should have consistent hierarchical structure for meaningful results
- Specs should be provided as a list of (index, spec_tuple) pairs where index is a unique identifier
- For string matching, longer common prefixes are prioritized over shorter ones
- For numeric matching, smaller absolute differences are prioritized
- The function handles numpy boolean types by converting them to Python booleans before comparison
- If no match is found at the top level (depth 0), the function returns None rather than attempting a partial match
- The recursion depth parameter should typically be left at its default value of 0 when calling from external code
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function match_spec 79.4% similar
-
function iterative_select 51.6% similar
-
function get_overlay_spec 48.0% similar
-
function get_spec 45.5% similar
-
function group_select 44.1% similar