处理数据提要格式

本文关键字:格式 数据 处理 | 更新日期: 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);