У меня есть vector
пар ключ-значение, где каждая пара ключ-значение также помечена кодом типа ввода. Возможные коды типа ввода:
enum Type
{
tData = 0,
tSeqBegin = 1, // the beginning of a sequence
tSeqEnd = 2 // the end of a sequence
};
Таким образом, сама пара ключ-значение выглядит следующим образом:
struct KeyVal
{
int key_;
string val_;
Type type_;
};
Внутри вектора находятся под-массивы дополнительных пар ключ-значение. Эти подмассивы называются «последовательностями». Последовательности могут быть вложены на любой уровень. Таким образом, последовательности могут иметь (необязательные) подпоследовательности различной длины. Комбинация Ключа и Type
уникальна в элементе последовательности . То есть внутри одного элемента последовательности может быть только одна строка данных 269
, но другие элементы последовательности могут иметь свои собственные строки данных 269
.
Вот графическое представление некоторых выборочных данных, чрезмерно упрощенное (если столбец «Тип» пустой, он имеет тип tData
):
Row# Type Key Value
---- ------------- ----- --------
1 35 "W"
2 1181 "IBM"
3 tSeqBegin 268 "3"
4 269 "0"
5 270 "160.3"
6 tSeqEnd 0
7 269 "0"
8 290 "0"
9 tSeqBegin 453 "1" <-- subsequence
10 tSeqEnd 0 <-- end of subsequence
11 tSeqEnd 0
12 269 "0"
13 290 "1"
14 270 "160.4"
15 tSeqEnd 0
16 1759 "ABC"
[РЕДАКТИРОВАТЬ: примечание на выше. Есть один tSeqBegin
, который отмечает начало всей последовательности. Конец каждой последовательности элемент помечен tSeqEnd
. Но не существует специального tSeqEnd
, который также отмечает конец всей последовательности. Таким образом, для последовательности вы увидите 1 tSeqBegin
и n
tSeqEnd
s, где n
- количество элементов в последовательности.
Другое примечание: в приведенной выше последовательности, начинающейся в строке № 3 и заканчивающейся в строке № 15, во 2-м элементе есть одна подпоследовательность (строки 7–11). Подпоследовательность пуста и занимает строки 9 и 10.]
Я пытаюсь найти элемент последовательности, который имеет множественное значение Key-Value, соответствующее определенным критериям. Например, предположим, что я хочу найти элемент последовательности, который имеет как 269="0"
, так и 290="0"
. В этом случае он не должен найти элемент # 0 (начиная со строки 3), потому что этот элемент вообще не имеет строки 290=...
. Вместо этого он должен найти элемент, начинающийся с строки № 7. В конечном итоге я извлеку другие поля из этого элемента, но это выходит за рамки этой проблемы, поэтому я не включил эти данные выше.
Я не могу использовать std::find_if()
, потому что find_if()
будет оценивать каждую строку отдельно, а не весь элемент последовательности как единое целое. Поэтому я не могу построить функтор, который оценивает что-то вроде if 269=="0" &&* 290=="0"
, потому что ни одна строка никогда не оценит это как true
.
Я думал реализовать свою собственную функцию find_sequence_element(...)
. Но это предполагает довольно сложную логику. Сначала я должен был бы идентифицировать begin()
и end()
всей последовательности, отмечая, где каждый элемент begin()
и end()
. Тогда мне нужно было бы построить какую-то структуру оценки, которую я мог бы связать вместе, как этот псевдокод:
Condition cond = KeyValueMatch(269, "0") + KeyValueMatch(290, "0");
Но это тоже сложно. Я не могу просто построить find_sequence_element()
, который принимает ровно 2 параметра, один для совпадения 269
и другой для совпадения 290
, потому что я хочу использовать этот алгоритм и для других последовательностей, с большим или меньшим количеством условий .
Более того, похоже, я должен быть в состоянии использовать уже существующие STL <algorithm>
. Хотя я достаточно хорошо знаю STL, я не могу найти способ использовать find_if()
каким-либо простым способом.
Итак, наконец, вот вопрос. Если бы вы столкнулись с вышеуказанной проблемой, как бы вы ее решили? Я знаю, что вопрос неясен. Я надеюсь, что после некоторого обсуждения мы сможем сузить проблемную область, пока у нас не будет ответа.
Некоторые условия:
(Если все согласны с тем, что это должен быть CW, я отмечу это так)