在col [1]等于先前的col [1]迭代时获取col [0]的值

时间:2018-07-12 19:03:22

标签: c# .net arraylist

我正在使用美国联邦储备网站的价格表,其中包含两个列 [0] == ShortDate(例如“ 1/1/1962”) [1] ==该日期在[0]中的汇率

文件的格式如下: 1/1 / 1962,3.8

此实用程序每次运行时,它都会获取/打开文件,并删除1997年5月31日及之前的所有数据。然后,它使用以下标头写入流(在我的情况下为另一个csv文件): rowid,beginningdate,expirationdate,rate

我遇到的问题是,部分要求是,如果汇率(col [1])在连续几天中具有相同的值,则不要特别列出那些日子。相反,请写出第一个连续汇率的日期,然后写出再次改变汇率之前的最后一个日期。

我的问题/问题是:

如何在循环之前和之后检查每个迭代的col [1]值,以便可以正确编写开始日期和到期日期?我希望将值的索引增加一个,这样我就可以在下一行中获取值,但是很难做到这一点。

我已经尝试过使用尽可能多的基于Linq的查询进行研究,但是我找不到任何可行的方法,只需要另一双眼睛/另一个想法即可。

这是我到目前为止正在做的事情:

int count=0;
var rateContents = File.ReadAllLines(resFile);
List<DateTime> lstDT = new List<DateTime>();
List<string> lstRate = new List<string>();
List<string> d = new List<string>();

foreach (var x in rateContents)
{
   lstDT.Add(Convert.ToDateTime(x.Split(',')[0]));
   lstRate.Add(x.Split(',')[1]);
}

int recordsOn_and_after6_1_97 = lstDT.Where(z => Convert.ToDateTime(z) >= Convert.ToDateTime("6/1/1997")).Count();
int recordsbefore6_1_97 = lstDT.Where(z => Convert.ToDateTime(z) < Convert.ToDateTime("6/1/1997")).Count();
lstRate.RemoveRange(0, recordsbefore6_1_97);
lstDT.RemoveRange(0, recordsbefore6_1_97);

using (StreamWriter sw = new StreamWriter(desktoppath + "somefile.csv"))
{
   while (count <= (recordsOn_and_after6_1_97 - 1))
   {
    //sw.WriteLine("Index Number,Effective Date,Expiration Date,Rate");
    d.Add(Convert.ToDateTime(lstDT[count].ToShortDateString()) + "," + lstRate[count]);
    count++;
   }
}

count = 0;
/*Below is where I am stuck. Realistically I think I'd want to do something like: var variable = argh.val[count+1]; or something, but I can't get that to work either. I'm missing something simple at this point.*/
foreach (var argh in d.Select((val, ind) => new { Value = val, Index = ind}))
{
   //var curdt = Convert.ToDateTime(argh.Split(',')[0]).ToShortDateString();
   //var currate = argh.Split(',')[1].ToString();
   var curdt = argh.Value.Split(',')[0];
   var currate = argh.Value.Split(',')[1];
   var x = currate.CompareTo(currate[count + 1].ToString()).ToString() ;
   Console.WriteLine(x.ToString());
   //Console.WriteLine("val +1: " + curdt + " --- rate: " + currate.TakeWhile(z => z <= 10).ToString());
   count++;
   //Console.WriteLine(prevcurdt +" --- "+ currate);
}

请保持温柔,我仍然每天都在学习新事物:-) 谢谢!

1 个答案:

答案 0 :(得分:1)

这是我的想法,可以根据需要过滤费率。基本上,这只是一个简单的for循环,它查看当前速率的任一侧-如果下一个速率不同,则我们知道当前日期是我们当前正在使用的任何条目的到期日期。如果最后一个速率不相同,我们就知道它是一个新条目。

public class RateEntry
{
    public DateTime StartDate { get; set; }
    public DateTime ExpirationDate { get; set; }
    public decimal Rate { get; set; }
}

class Program
{

    const string DATE_FORMAT_IN = "yyyy-MM-dd";
    const string DATE_FORMAT_OUT = "yyyy-MM-dd";

    static void Main()
    {
        var inputRateDataRaw = File.ReadAllLines(@"c:\temp\RATES_IN.csv");

        DateTime startDate = new DateTime(1997, 05, 31);

        // parse the input dates and rates
        var rateDataFiltered = inputRateDataRaw
            .Select(rateData =>
            {
                var dataComponents = rateData.Split(',');
                DateTime rateDate = DateTime.ParseExact(dataComponents[0], DATE_FORMAT_IN, null);
                decimal rate = decimal.Parse(dataComponents[1]);
                return new RateEntry() { StartDate = rateDate, Rate = rate };
            })
            .Where(a => a.StartDate > startDate)
            .OrderBy(a => a.StartDate)
            .ToList();            

        List<RateEntry> rateRanges = new List<RateEntry>();

        for (int i = 0; i < rateDataFiltered.Count; i++)
        {
            RateEntry next = ((i + 1) == rateDataFiltered.Count) ? null : rateDataFiltered[i + 1];
            RateEntry last = (i == 0) ? null : rateDataFiltered[i - 1];
            RateEntry now = rateDataFiltered[i];
            // if this is the first rate, or if the last rate isn't this rate, this is a new entry.
            if (last == null || last.Rate != now.Rate)                
                rateRanges.Add(now); 
            // if the next rate isn't this one, then the current entry expiration is this one's start date.
            if (next == null || next.Rate != now.Rate) 
                rateRanges.Last().ExpirationDate = now.StartDate; 
        }

        // write the data out
        using (StreamWriter writer = new StreamWriter(@"c:\temp\RATES_OUT.csv"))
        {
            writer.WriteLine("ROWID;STARTDATE;EXPIRATIONDATE;RATE");

            for (int i = 0; i < rateRanges.Count; i++)
            {
                RateEntry rateEntry = rateRanges[i];
                writer.WriteLine($"{i};{rateEntry.StartDate.ToString(DATE_FORMAT_OUT)};{rateEntry.ExpirationDate.ToString(DATE_FORMAT_OUT)};{rateEntry.Rate}");
            }
        }

        Console.ReadKey();
    }
};