Почему это, если утверждение не в состоянии оценить условие? - PullRequest
0 голосов
/ 06 ноября 2018

Я имею дело со следующей ситуацией:

{[x;y]first{[x;y] 
              if[not null first ss[x;raze string[y],"="];
              ind:ss[x;raze string[y],"="];
              pt1:(first ind)#x;
              pt2:((first ind)+count[raze string[y],"="]) _ x;
              pt2:(first ss[pt2;"|"]) _ pt2;
              x:pt1,(string[y],"=test_TAG_",string[.z.P]),pt2];
              :x
           }\[y;x]}[fields;]each a;

Итак, что код делает:

1. Takes each string a in the form of a fix message "TAG=value|TAG2=value2 ..."
2. Takes variable fields which contains either 1, 2, 3 ...n symbols. 
3. Searches through the string fro the field, finds the index adds value after "=". 
4. [...] keeps doing that until all the values in fields have been depleted

Проблема в том, что оператор if не проверяет значение. Если это 0b или 1b, он продолжает работать и выполняет ind:ss[x;raze string[y],"="], несмотря ни на что. Почему это происходит?

1 Ответ

0 голосов
/ 06 ноября 2018

Кажется, как будто

first {}\[]

фактически заставило вашу функцию вернуть первоначальный результат. Scan будет проходить через каждое поле, но first будет отбрасывать их и возвращать только первую итерацию строки.

Использование over в приведенном ниже синтаксисе позволит вам выполнить эту операцию и вернуть окончательную версию строки.

f
{[x;y]{[x;y]
              if[not null first ss[x;raze string[y],"="];
              ind:ss[x;raze string[y],"="];
              pt1:(first ind)#x;
              pt2:((first ind)+count[raze string[y],"="]) _ x;
              pt2:(first ss[pt2;"|"]) _ pt2;
              x:pt1,(string[y],"=test_TAG_",string[.z.P]),pt2];
              :x
           }/[y;x]}
q)a
"1=abc|3=44.4|9=4000"
"1=xyz|3=55.5|5=99|9=2000"
q)fields:1 3 99
q)r:f[fields] each a
q)r
"1=test_TAG_2018.11.06D10:18:14.574411000|3=test_TAG_2018.11.06D10:18:14.574431000|9=4000"
"1=test_TAG_2018.11.06D10:18:14.574447000|3=test_TAG_2018.11.06D10:18:14.574458000|5=99|9=2000"

Исходя из этих выборок, функция, похоже, правильно пропускает неопределенный тег (например, тег 99 в приведенном выше примере). Если бы вы могли привести пример, где это не так, возможно, это можно проверить.

Кроме того, есть только несколько ошибок, связанных с соответствием тега>

1) Частичные теги будут сопоставлены, в случае если поиск по 3 был выполнен, любой тег, заканчивающийся на 3, вызовет совпадение.

q)a:("1=abc|3=44.4|9=4000";"1=xyz|3=55.5|5=99|9=2000";"1=jkl|33=50|66=0")
q)f[fields] each a
"1=test_TAG_2018.11.06D11:51:09.469637000|3=test_TAG_2018.11.06D11:51:09.469653000|9=4000"
"1=test_TAG_2018.11.06D11:51:09.469666000|3=test_TAG_2018.11.06D11:51:09.469674000|5=99|9=2000"
"1=test_TAG_2018.11.06D11:51:09.469685000|33=test_TAG_2018.11.06D11:51:09.469694000|66=0"

2) Кроме того, если соответствующий тег находится в последнем разделе и нет закрывающего |, код не будет работать должным образом. Это, конечно, зависит от структуры сообщения.

q)f[3 9] "1=abc|3=44.4|9=4000"
{[x;y]
...
           }
'type
_
0N
"4000"

Следует отметить, что при сохранении его в виде строки будет изначально более эффективным, если имеется более пары полей, использование 0: для анализа пар ключ-значение будет быстрее и предотвратит любое из отмеченные крайние случаи от возникновения.

...