从LINQ中的字符串列表中选择最大数量?

时间:2016-05-24 13:18:35

标签: c# linq

尝试从字符串列表中选择最大数字:

 int maxDigit = this.myList.Where(x=> x.Name.Any(Char.IsDigit))
                .Select(x => int.Parse(x.Name)).DefaultIfEmpty(0).Max();

导致异常的是int.Parse(x.Name),因为这会返回整个名称字符串,例如'myValue99'当然无法解析为int。我只想返回99.我不知道数字在字符串中的位置,因此不能用例如最后两个。

对于字符串不包含数字的情况,我需要DefaultIfEmpty。

6 个答案:

答案 0 :(得分:4)

假设您需要max 数字而不是max 数字,您只需要将"stuff99"转换为99的功能。然后Linq部分变成了孩子的游戏:

int maxNumber = myList.Max(ExtractNumberFromText);

或者,更接近您的规格:

int maxNumber = myList
         .Select(ExtractNumberFromText)
         .DefaultIfEmpty(0)
         .Max(); 

@Codecaster已经在第二部分的网站上指出了一些适用的答案。我采用了一个简单的。没有错误检查。

// the specs: Only ever going to be my stuff1, stuff99     
int ExtractNumberFromText(string text)
{      
   Match m = Regex.Match(text, @"\d*");            
   return int.Parse(m.Groups[0].Value);       // exception for "abc"
       // int.Parse("0" + m.Groups[0].Value); // use this for default to 0
}

答案 1 :(得分:3)

您应该只选择并解析字符串中的数字字符

{{1}}

答案 2 :(得分:0)

使用正则表达式可以很简单。

您声明 99 ,因此您需要跨越多个数字

var maxNumber = myTestList.SelectMany(x => getAllNumnbersFromString(x.Name)).DefaultIfEmpty(0).Max();

static List<int> getAllNumnbersFromString(string str)
{
    List<int> results = new List<int>();

    var matchesCollection = Regex.Matches(str, "[0-9]+");

    foreach (var numberMatch in matchesCollection)
    {
        results.Add(Convert.ToInt32(numberMatch.ToString()));
    }

    return results;
}

仅限一位数检查:

int maxNumber = myTestList.SelectMany(x => x.Name.ToCharArray().ToList())
                            .Select(x => Char.IsDigit(x) ? (int)Char.GetNumericValue(x) : 0)
                            .DefaultIfEmpty(0).Max();

答案 3 :(得分:0)

要在每个字符串中找到最大数字(而不是数字):

static void Main(string[] args)
{
    List<string> strList = new List<string>() { "Value99", "46Text" };
    List<int> resultList = new List<int>();

    foreach (var str in strList)
    {
        char[] resultString = Regex.Match(str, @"\d+").Value.ToCharArray();
        int maxInt = resultString.Select(s => Int32.Parse(s.ToString())).Max();
        resultList.Add(maxInt);
    }
} 

答案 4 :(得分:0)

假设输入可以包含以下类别:

  • nullŠ
  • 空字符串
  • 仅包含字母字符的字符串
  • 具有混合字母和数字字符的字符串
  • 仅包含数字字符的字符串

您想引入一个提取数字的方法(如果有的话),或者如果不是,则返回一个有意义的值:

private static int? ParseStringContainingNumber(string input)
{
    if (String.IsNullOrEmpty(input))
    {
        return null;
    }

    var numbersInInput = new String(input.Where(Char.IsDigit).ToArray());
    if (String.IsNullOrEmpty(numbersInInput))
    {
        return null;
    }

    int output;

    if (!Int32.TryParse(numbersInInput, out output))
    {
        return null;
    }

    return output;
}

请注意,并非所有Char.IsDigit返回true的字符都可由Int32.Parse()解析,因此TryParse

然后您可以将列表提供给此方法:

var parsedInts = testData.Select(ParseStringContainingNumber)
                         .Where(i => i != null)
                         .ToList();

使用parsedInts列表执行任何操作,例如在其上调用IEnumerable<T>.Max()

使用以下测试数据:

var testData = new List<string>
{
    "۱‎", // Eastern Arabic one, of which Char.IsDigit returns true.
    "123",
    "abc456",
    null,
    "789xyz",
    "foo",
    "9bar9"
};

返回:

123
456
789
99

特别注意最新案例。

答案 5 :(得分:-1)

可能有一种更明智的方法可以做到这一点,但我会这样做:

int tmp = 0;
int maxDigit = this.myList.Where(x=> x.Name.Any(Char.IsDigit))
                .Select(x => 
(int.TryParse(x.Name,out tmp ) ? int.Parse(x.Name) : 0 ) ).Max();

你必须记住,如果Parse无法解析该值,Parse会出错,但TryParse只会给你错误。