使用Linq获取要输出的匹配数据

本文关键字:数据 输出 Linq 获取 使用 | 更新日期: 2023-09-27 18:17:49

我有两个文件,它们被读入不同的数组,如:

String[] leaseName2 = new String[1000];
String[] fieldName2 = new String[1000];
String[] reservoir2 = new String[1000];
String[] operator2 = new String[1000];
String[] county2 = new String[1000];
String[] state2 = new String[1000];
String[] majo2 = new String[1000];
String[] resvCatgory2 = new String[1000];
String[] netOil2 = new String[1000];
String[] netGas2 = new String[1000];
String[] netNGL2 = new String[1000];
String[] leaseName = new String[1000];
String[] fieldName = new String[1000];
String[] reservoir = new String[1000];
String[] operator1 = new String[1000];
String[] county = new String[1000];
String[] state = new String[1000];
String[] majo = new String[1000];
String[] resvCatgory = new String[1000];
String[] netOil = new String[1000];
String[] netGas = new String[1000];
String[] netNGL = new String[1000];

然后我用Linq合并两个文件,合并两个匹配的数组,如netOilnetOil2,给我一个double的答案。有一堆不同的行数据是由相同的seqNum数组匹配的。

String[] seqNum2 = new String[1000]; //This will be the identifier
String[] seqNum = new String[1000]; //This will be the identifier

我遇到的问题是输出所有相应的数据,如leaseName[]fieldname[]reservoir[]与识别seqNum数组。下面是我的Linq代码:

private void executeBtn_Click(object sender, EventArgs e)
{
    //NET OIL VARIANCE MATHEMATICS
    if (netOilRadBtn.Checked)
    {
        using (var sw = new StreamWriter("testNetOil.csv"))
        {
            var items = netOil.Zip(seqNum, (oil, seq) => new {Oil = oil, Seq = seq });
            var items2 = netOil2.Zip(seqNum2, (oil, seq) => new { Oil = oil, Seq = seq });
            sw.WriteLine("Lease Name, Field Name, Reservoir, Operator, County, ST, Majo, Resv Cat, Discount Rate, Net Oil Interest, Net Gas Interest, Working Interest, Gross Wells, Ultimate Oil, Ultimate Gas, Gross Oil, Gross NGL, Gross Gas, Net Oil, Net Gas, Net NGL, Revenue To Int., Oper. Expense, Total Invest., Revenue Oil, Revenue Gas, Operating Profit, Revenue NGL, Disc Net Income, SEQ, Well ID, INC ASN, Life Years, Own Qual, Production Tax, NET OIL VARIANCE");
            foreach (var item in items2.Join(items, i => i.Seq, i => i.Seq, (a, b) => new
            {
                SeqID = a.Seq,
                Answer = this.GetTheAnswer(Convert.ToDouble(a.Oil), Convert.ToDouble(b.Oil)),

                //OilNum1 = a.Oil, GIVES FIRST OIL FROM NET OIL ARRAY 1, item.oilnum1 will print out first oil #
                //OilNum2 = b.Oil, GIVES SECOND OIL FROM NET OIL ARRAY 2, item.OilNum2 ********
            }))
            {
                sw.WriteLine(item.SeqID + "," + item.Answer); //this prints out the seqNum and Answer that I want to match with all of the other data in the arrays

                /*  commented out to see what I've tried
                int x = listHead;
                x.Equals(item.SeqID);
                while (x != -1)
              {
                   sw.WriteLine("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, {26}, {27}, {28}, {29}, {30}, {31}, {32}, {33}, {34}, {35}, {36}",
            QuoteString(leaseName[x]), fieldName[x], QuoteString2(reservoir[x]), operator1[x], county[x], state[x], majo[x], resvCatgory[x], disRate[x], netOil2Int[x], netGas2Int[x], workingInt[x], grossWells[x]
            , ultOil[x], ultGas[x], grossOil[x], grossNGL[x], grossGas[x], netOil[x], netGas[x], netNGL[x], revToInt[x], operExpense[x], totInvest[x], revOil[x], revGas[x], operatingProfit[x],
            revNGL[x], discNetIncome[x], seqNum[x], wellID[x], incASN[x], lifeYears[x], ownQual[x], prodTax[x], item.SeqID, item.Answer);
                   x = pointers[x];

                   //sw.WriteLine(item);
                }*/
            }
            sw.Close();
        }
    }

我无法在foreach循环中打印出与seqNum匹配的所有数据,因此我试图创建另一个循环,但这打印出了大量无用的额外数据。如果有人对如何在我用Linq代码获得Answer后用seqNum打印出所有数据有任何想法,如果你能让我知道,我会很感激的。

使用Linq获取要输出的匹配数据

我建议你在尝试使用c#和LinQ之前学习和练习一些基本的编程入门和OOP。

  • 首先,拥有11个字符串数组的想法是令人厌恶的。您应该学习如何创建一个合适的数据模型并这样做。

    public class MyRecord
    {
        public int SeqNum {get;set;} // Notice the proper case in property names
        public string LeaseName {get;set;}
        public string FieldName {get;set;}
        public string Reservoir {get;set;}
        //... Etc.
    }
    
  • 然后,花点时间分析一下所有属性都是string是否是个好主意。例如,如果一个属性只能有数值,那么最好使用强类型并使用intdouble。如果一个属性只能有"真"或"假"值,那就是bool,以此类推。

我遇到的问题是输出所有相应的数据例如leaseName[]和fieldname[]以及reservoir[]识别seqNum数组。

这是因为你的数据是以最糟糕的方式建模的。如果像上面那样创建一个类,就不会有这个问题,因为属于同一条记录的所有数据都在这个类的同一个实例中。然后:

List<MyRecord> File1 {get;set;}
List<MyRecord> File2 {get;set;}
var myrecord = File1.FirstOrDefault(x => x.SeqNum == someSeqNum);
var leasename = myrecord.LeaseName;
var reservoir = myrecords.Reservoir;
//... etc

看到生活其实有多容易了吗?

  • 最重要的是,为了人类,请从UI后面的代码中删除您的业务逻辑。创建适当的服务,使用相关的方法和相关的参数,以隔离该功能并能够重用它。

    private void executeBtn_Click(object sender, EventArgs e)
    {
        MyService.ProcessRecords(relevant,parameters,from,the,UI);
    }