为了账号安全,请及时绑定邮箱和手机立即绑定

Linq返回下一行有值的当前行

Linq返回下一行有值的当前行

C#
宝慕林4294392 2022-07-23 17:25:28
我需要处理作为单个 Excel 字符串列提供给我的发票,我已将其转换为List<string>. 一个简化的示例如下所示。This is a nothing lineNo001 FOO67 368.80No001 FOO67 17.68SHORT 12345在此示例中,我可能需要从以“No”开头的每一行中提取数据——参考(例如 FOO67)和数量(例如 368.80)。但是,如果我遇到以“SHORT”开头的行,这意味着之前的行金额确实是一个调整,并且参考应该是我在“SHORT”行上找到的任何内容,并且金额的符号相反。在上述情况下,我希望提取的数据如下(第一行是列标题):Reference    Amount  FOO67      368.80  12345      -17.68我找不到使用针对列表的 linq 查询来实现此目的的任何方法。我认为解决方案可能看起来像这样的模型(下面不会解析,因为我添加了“nextline”作为伪代码添加):var inv = new List<string> { "This is a nothing line", "No001 FOO67 368.80", "No001 FOO67 17.68", "SHORT 123456" };var myTable = new DataTable();myTable.Columns.Add("Id", typeof(int));myTable.Columns.Add("Ref", typeof(string));myTable.Columns.Add("Amount", typeof(double));var foo = from l in inv            where (l.Substring(0, 2) == "No" && double.TryParse(l.Split(' ')[2], out i))            select myTable.LoadDataRow(new object[]                    { inv.IndexOf(l)                     ,nextline.Contains("SHORT")? nextline.Split(' ')[1] : l.Split(' ')[1]                     ,nextline.Contains("SHORT")? -1:1 * double.Parse(l.Split(' ')[2].Replace(",", "").Replace("-", ""))                    }, LoadOption.OverwriteChanges);有没有一种已知的方法可以从查询的下一行获取值并使用它来决定要返回哪些行?如果是这样,这样做的方法是什么?
查看完整描述

2 回答

?
守着星空守着你

TA贡献1799条经验 获得超8个赞

您可以使用以下内容。


var inv = new List<string> 

                { 

                 "This is a nothing line", 

                 "No001 FOO67 368.80", 

                 "No001 FOO67 17.68", 

                 "SHORT 123456" 

                };


var filterValidLines = inv.ToLookup(c=>c.StartsWith("No") 

                                              ||c.StartsWith("SHORT"));

var result = filterValidLines[true].Zip(

                            filterValidLines[true].Skip(1),

                            (x,y)=>

    var subData= x.Split(new []{" "},StringSplitOptions.RemoveEmptyEntries);

    var multiplier = y.StartsWith("SHORT")? -1:1;

    return new Data{Reference= subData[1], Amount = double.Parse(subData[2]) * multiplier};

});

输出


Reference Amount

FOO67     368.8 

FOO67     -17.68 


查看完整回答
反对 回复 2022-07-23
?
ITMISS

TA贡献1871条经验 获得超8个赞

一个快速而肮脏的解决方案:


void Main()

{

    var list = new List<string>

    {

        "This is a nothing line",

        "No001 FOO67 368.80",

        "No001 FOO67 17.68",

        "SHORT 12345"

    };



    var invoices = list

        .Select((l, i) => new InvoiceData

        { 

            Line = l, 

            NextLine = i < list.Count - 1 ? list[i + 1] : string.Empty 

        })

        .Where(x => x.Line.StartsWith("No"))

        .ToList();

}


public class InvoiceData

{

    public string Line { get; set; }

    public string NextLine { get; set; }

    public bool IsAdjustment => NextLine.StartsWith("SHORT");

    public decimal Amount =>

        IsAdjustment 

            ? -decimal.Parse(Line.Split(' ')[2])

            : decimal.Parse(Line.Split(' ')[2]);

    public string Reference =>

        IsAdjustment

            ? NextLine.Split(' ')[1]

            : Line.Split(' ')[1];

}


查看完整回答
反对 回复 2022-07-23
  • 2 回答
  • 0 关注
  • 112 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号