Added search method.

This commit is contained in:
Fabio Caccamo 2020-01-13 14:53:16 +01:00
parent 6f90c28509
commit 77a3b94f5b
3 changed files with 69 additions and 0 deletions

View File

@ -125,6 +125,12 @@ class benedict(IODict, KeypathDict, ParseDict):
"""
dict_util.rename(self, key, key_new)
def search(self, query, in_keys=True, in_values=True, exact=False, case_sensitive=False):
"""
Search and return a list of items (dict, key, value, ) matching the given query.
"""
return dict_util.search(self, query, in_keys, in_values, exact, case_sensitive)
def standardize(self):
"""
Standardize all dict keys (e.g. 'Location Latitude' -> 'location_latitude').

View File

@ -155,6 +155,26 @@ def resolve(d, keys, **kwargs):
return result
def search(d, query, in_keys=True, in_values=True, exact=False, case_sensitive=True):
items = []
def s(value):
# TODO: add regex support
q_is_str = isinstance(query, string_types)
q = query.lower() if q_is_str and not case_sensitive else query
v_is_str = isinstance(value, string_types)
v = value.lower() if v_is_str and not case_sensitive else value
if exact:
return q == v
elif q_is_str and v_is_str:
return q in v
return False
def f(item_dict, item_key, item_value):
if (in_keys and s(item_key)) or (in_values and s(item_value)):
items.append((item_dict, item_key, item_value, ))
traverse(d, f)
return items
def standardize(d):
def f(item, item_key, item_value):
if isinstance(item_key, string_types):

View File

@ -1225,6 +1225,49 @@ b:
with self.assertRaises(KeyError):
b.rename('aa', 'b')
def test_search(self):
d = {
'a': 'Hello world',
'b': 'Hello world!',
'c': {
'd': True,
'e': ' hello world ',
'f': {
'g': 'HELLO',
'h': 12345,
'hello': True,
},
},
'Hello world': 'Hello World',
}
b = benedict(d)
results = b.search('Hello', in_keys=False, in_values=False, exact=True, case_sensitive=True)
self.assertEqual(len(results), 0)
self.assertEqual(results, [])
results = b.search('Hello', in_keys=False, in_values=True, exact=True, case_sensitive=True)
self.assertEqual(len(results), 0)
self.assertEqual(results, [])
results = b.search('Hello', in_keys=False, in_values=True, exact=True, case_sensitive=False)
self.assertEqual(len(results), 1)
self.assertTrue((d['c']['f'], 'g', d['c']['f']['g'], ) in results)
results = b.search('hello', in_keys=True, in_values=True, exact=False, case_sensitive=False)
self.assertEqual(len(results), 6)
self.assertTrue((d, 'a', d['a'], ) in results)
self.assertTrue((d, 'b', d['b'], ) in results)
self.assertTrue((d['c'], 'e', d['c']['e'], ) in results)
self.assertTrue((d['c']['f'], 'g', d['c']['f']['g'], ) in results)
self.assertTrue((d['c']['f'], 'hello', d['c']['f']['hello'], ) in results)
self.assertTrue((d, 'Hello world', d['Hello world'], ) in results)
results = b.search('hello', in_keys=True, in_values=False, exact=False, case_sensitive=False)
self.assertEqual(len(results), 2)
self.assertTrue((d['c']['f'], 'hello', d['c']['f']['hello'], ) in results)
self.assertTrue((d, 'Hello world', d['Hello world'], ) in results)
# def test_setdefault(self):
# d = {
# 'a': 1,