cti-python-stix2/stix2/equivalence/pattern/compare/__init__.py

100 lines
2.4 KiB
Python
Raw Normal View History

"""
Some generic comparison utility functions.
.. autosummary::
:toctree: compare
comparison
observation
|
"""
2020-08-13 23:44:42 +02:00
def generic_cmp(value1, value2):
"""
Generic comparator of values which uses the builtin '<' and '>' operators.
Assumes the values can be compared that way.
:param value1: The first value
:param value2: The second value
:return: -1, 0, or 1 depending on whether value1 is less, equal, or greater
than value2
"""
return -1 if value1 < value2 else 1 if value1 > value2 else 0
def iter_lex_cmp(seq1, seq2, cmp):
"""
Generic lexicographical compare function, which works on two iterables and
a comparator function.
:param seq1: The first iterable
:param seq2: The second iterable
:param cmp: a two-arg callable comparator for values iterated over. It
must behave analogously to this function, returning <0, 0, or >0 to
express the ordering of the two values.
:return: <0 if seq1 < seq2; >0 if seq1 > seq2; 0 if they're equal
"""
it1 = iter(seq1)
it2 = iter(seq2)
it1_exhausted = it2_exhausted = False
while True:
try:
val1 = next(it1)
except StopIteration:
it1_exhausted = True
try:
val2 = next(it2)
except StopIteration:
it2_exhausted = True
# same length, all elements equal
if it1_exhausted and it2_exhausted:
result = 0
break
# one is a prefix of the other; the shorter one is less
elif it1_exhausted:
result = -1
break
elif it2_exhausted:
result = 1
break
# neither is exhausted; check values
else:
val_cmp = cmp(val1, val2)
if val_cmp != 0:
result = val_cmp
break
return result
def iter_in(value, seq, cmp):
"""
A function behaving like the "in" Python operator, but which works with a
a comparator function. This function checks whether the given value is
contained in the given iterable.
:param value: A value
:param seq: An iterable
:param cmp: A 2-arg comparator function which must return 0 if the args
are equal
:return: True if the value is found in the iterable, False if it is not
"""
result = False
for seq_val in seq:
if cmp(value, seq_val) == 0:
result = True
break
return result