我处理以下情况:
{[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],"="]
。为什么会这样呢?
答案 0 :(得分:3)
好像
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:
解析键值对会更快,并且会阻止任何上述的极端情况都不会发生。