处理数据提要格式
本文关键字:格式 数据 处理 | 更新日期: 2023-09-27 18:10:19
前几天我遇到了一个有趣的面试问题,我真的很纠结。这个(雄心勃勃的)规范要求我用c#为两种不同的数据流编写解析器。下面是第一个流的一个虚构的例子:
30=EUR/USD,35=3,50=ON,51=12.5,52=13.5,50=6M,51=15.4,52=16.2,50=1Y,51=17.2,52=18.3
其中30为货币对,35为男高音数量,50、51、52分别为男高音、买入价和卖出价。买入价和卖出价是可选的,但是一个正确的tenor-bid-ask元组将至少有两个价格中的一个。他们提供的框架代码暗示解析这一行的结果应该是3个单独的对象(DataElement实例)。我最终得到了一个相当糟糕的开关语句和基于循环的实现,我不确定它是否真的有效。
有哪些技术可以读取这种类型的流?我试着用递归算出一些东西,但我做错了。
编辑:根据@evanmcdonnall的回答(接受),这里是完整的编译和工作代码,以防它对其他人有用。
List<DataElement> Parse(string row)
{
string currency=string.Empty;
DataElement[] elements = null;
int j = 0;
bool start = false;
string[] tokens = row.Split(',');
for (int i = 0; i < tokens.Length; i++)
{
string[] kv = tokens[i].Split('=');
switch (kv[0])
{
case "30":
currency = kv[1];
break;
case "35":
elements = new DataElement[int.Parse(kv[1])];
break;
case "50":
if (start)
j++;
elements[j] = new DataElement() { currency = currency, tenor = kv[1] };
start = true;
break;
case "51":
elements[j].bid = double.Parse(kv[1]);
break;
case "52":
elements[j].ask = double.Parse(kv[1]);
break;
}
}
return elements.ToList();
}
主要概念是:
- 为每行重复项的"内循环"设置一个单独的计数器
- 有一个布尔标志来指示"内循环"何时开始
- 分配对象数组,以在已知长度的点(即标签50)存储"内循环"结果
- 为了简单和清晰,让一个函数只读取一行,然后从一个单独的函数中多次调用它。
我不明白这有什么棘手的。然而,我没有看到任何解决方案会比我脑海中非常具体的,具有许多条件的迭代解决方案更好。
首先分割逗号,然后循环遍历这些令牌,在等号上分割每个令牌以获得键值对。您可以检查每个键和bool来跟踪何时开始/完成一个项目。你读取货币并将其用于每个对象。你读取键35
,发现有3个对象,所以你分配一个包含3个对象的数组,每个对象有3个属性;男高音,出价,再出价。当你遇到50时,你应该设定一个正确的起点。设置50 51 52,如果有的话。下面是一些示例代码;
string currency;
int j = 0;
bool start = false;
string[] tokens = line.Split(',');
for (int i =0; i < tokens.length; i++)
{
string[] kv = tokens[i].Split('=')
if (kv[0] == 30)
currency = kv[1]
elseif (kv[0] == 35)
{
DateElement[] elements = new DataElement[kv[1]];
}
elseif (kv[0] == 50)
{
if (start)
j++;
start = true; // flip your flag after the condition so it works for element 0
elements[j].currency = currency;
elements[j].tenor = kv[1];
}
elseif (kv[0] == 51)
elements[j].bid = kv[1];
elseif (kv[0] == 52)
elements[j].ask = kv[1];
// if these optional values aren't there we'll just fall back into the case for 50
// and everything will work as expected.
}
代码可能不漂亮,但逻辑相当简单,假设行格式正确,它总是可以工作的。
= 30欧元/美元,35 = 3 = 50,51 = 12.5,52 = 13.5,50 = 6米,51 = 15.4,52 = 16.2,50 y = 1, 51 = 17.2, 52 = 18.3
让我试试。我不是在写c#代码,只是概述一下我的方法
我将把它分成2段Chain1={P0, P1}和Chain2={P2......PN}
根据P1的值均匀地断开链2。基于逗号的位置。
substr=Chain.substring(0,Chain2.IndexOf(",", P1=3));
我们可以创建一个元组类集合-
here either i can use regex to split the string or simple substring and indexof("=") to extract value
var seg= new Tuple<string, int, int, >("ON", 12.5, 13.5);