linq中字符串中的最后一个整数

时间:2013-11-12 05:20:21

标签: c# linq

我有一个包含整数或字符串整数的列表 像这样

   TagNo      FTerminal
    1000         1
    1000         5
    1000         2S6

我怎样才能得到像这样的结果

   TagNo      FTerminal
    1000         1
                 5
                 6

我有这个,但肯定会在2s6上给我错误。 我怎样才能改变它以涵盖所有?

 var terminalList = sourceLists.Where(t => t.TagNo == tagList)
                               .Where(t=>t.FromTerminal.Length>0)
                               .Select(t => int.Parse(t.FromTerminal))
                               .OrderBy(t=>t)
                               .ToList();

6 个答案:

答案 0 :(得分:1)

您需要编写自己的函数,而不是在LINQ语句中使用int.Parse

这样的事情:

int parseTerminal(string input) {
    int result = -1;
    if (!int.TryParse(input, out result)) {
        result = -99;
    }
    return result;
}

那会使你的LINQ

var terminalList = sourceLists
               .Where( t => t.TagNo == tagList && t.FromTerminal.Length > 0 )
               .Select( t => parseTerminak(t.FromTerminal) )
               .OrderBy( t=>t )
               .ToList();

结果:

TagNo      FTerminal
1000       -99
           1
           5

你需要处理FromTerminal本身不是数字的特殊情况。

人们可以想到的要求的天真实现是这样的:

int parseTerminal(string input) {
    int result = -1;
    if (!int.TryParse(input, out result)) {
        var temporaryString = string.Empty;
        var lastInt = -1;

        input.ToList().ForEach( aChar => {
            if ( aChar >= '0' && aChar <= '9' ) {
                temporaryString += aChar;
            }  else {
                if ( temporaryString.Length >= 0 ) {
                    int.TryParse( temporaryString, out lastInt );
                    temporaryString = string.Empty;
                }
            }
        } );
        if ( temporaryString.Length >= 0 ) {
            if (!int.TryParse( temporaryString, out lastInt )) {
                lastInt = -98;
            }
        }
        result = lastInt;
    }
    return result;
}

注意:我不认为这个生产准备就绪,你应该考虑边缘情况。

答案 1 :(得分:0)

在不了解您的数据结构的情况下,我使用某些系统类型编写了代码。

var tuples = new List<Tuple<int, string>>
                 {
                     new Tuple<int, string>(1000, "1"),
                     new Tuple<int, string>(1000, "5"),
                     new Tuple<int, string>(1000,"2s6")
                 };
var enumerable = tuples.GroupBy(t => t.Item1).
    Select(g => new Tuple<int, List<int>>(g.Key, g.Select(e => int.Parse(Regex.Match(e.Item2, @"(?<=(\D|^))\d+(?=\D*$)").Value)).ToList()));

答案 2 :(得分:0)

如果最后一个符号始终为int,则可以像这样更改代码

var terminalList = sourceLists.Where(t => t.TagNo == tagList)
                           .Where(t=>t.FromTerminal.Length>0)
                           .Select(t => int.Parse(t.FromTerminal.Last()))
                           .OrderBy(t=>t)
                           .ToList();

<强>更新
如果不是只有一个可以像这样使用正则表达式的数字

var terminalList = sourceLists.Where(t => t.TagNo == tagList)
                           .Where(t=>t.FromTerminal.Length>0)
                           .Select(t => int.Parse(Regex.Match(t.FromTerminal, @"(\d+)$").Groups[1].Value))
                           .OrderBy(t=>t)
                           .ToList();

答案 3 :(得分:0)

发生错误是因为您尝试使用int.Parse字符串'2S6'作为整数处理。这自然会导致异常。

我建议使用正则表达式,遵循另一种方法。我认为正则表达式是更好的解决方案,因为你提出的数据来自已经检索到的查询结果的字符串操作之后的

使用正则表达式来完成此类工作,将使您在将来更容易维护。想想这种情况,在一周内你不想检索字符串的最后一位数字,而是要检索字符串的第二位数字。

您可以使用this online regular expression tester来测试正则表达式。我想正则表达式\d(?!.*\d)将是一个不错的选择,因为它返回最后一位数。

This article是在.NET中使用正则表达式的一个很好的指南,包括示例。

希望我帮忙!

答案 4 :(得分:0)

我很困惑你想要什么...因为你的图片说你想要 TagNO FTerminal 的组合,而另一方面你的查询说你想要只有特定顺序的FTerminals ..

现在,如果您想要第一个,那么

void Abc(int tagList)
{
    var sourceLists = new List<Demo>
    {
        new Demo { FTerminal = "200", TagNo = 1000 },
        new Demo { FTerminal = "300", TagNo = 1000 },
        new Demo { FTerminal = "400", TagNo = 1000 }
    };

    var terminalList = sourceLists
        .Where(t => t.TagNo == tagList && t.FTerminal.Length > 0)
        .OrderBy(i=>i.FTerminal).GroupBy(i=>i.TagNo);                                                               
}

第二个

void Abc(int tagList)
{

    var sourceLists = new List<Demo>
        {
          new Demo { FTerminal = "200", TagNo = 1000 },
          new Demo { FTerminal = "300", TagNo = 1000 },
          new Demo { FTerminal = "400", TagNo = 1000 }
        };

    var terminalList = 
        from Demo d in sourceLists
            where d.TagNo == tagList
            let number = int.Parse(d.FTerminal)
            orderby number ascending
            select number).ToList();
}

但是,如果你没有得到你想要的答案,请敲门!!!!

答案 5 :(得分:0)

嗯......而不是跳过篮球,只需使用IsInt ......问题解决了...... :)

var terminalList = sourceLists.Where(t => t.TagNo == tagList)
                           .Where(t=>t.FromTerminal.Length>0)
                           .Where(t => t.FromTerminal.IsInt() )
                           .Select(t => int.Parse(t.FromTerminal))
                           .OrderBy(t=>t)
                           .ToList();

(所以,只是将这个条件.Where(t => t.FromTerminal.IsInt() )添加到您的选择过程中)