C#如何从List中获取包含x编号的数字?

时间:2018-04-13 06:35:21

标签: c# list

    static void Main(string[] args)
    {
        List<int> Allnumber = new List<int>();
        Random rnd = new Random();
        while (true)
        {
            int dice = rnd.Next(1, 100);
            Console.WriteLine("Random number between 1 and 100 : {0}", dice);
            Allnumber.Add(dice);
            if (dice == 1)
                break;
        }

        Console.WriteLine();
        Console.WriteLine("Allnumber : " + string.Join(" ", Allnumber));
        List<int> Odd = (from number in Allnumber where number % 2 != 0 select number).ToList();
        List<int> Even = new List<int>(from number in Allnumber where number % 2 == 0 select number);
        Console.WriteLine("Odd : " + string.Join(" ", Odd));
        Console.WriteLine("Even : " + string.Join(" ", Even));

我想制作一个新列表,其中包括来自Allnumber列表的3个。 它应该包含所有具有3(3,13,23,33,34,36,39,43,53 ......)的数字。 无论如何只拿3s? 我发现有Findall,Contain方法但不能用于int类型列表。谢谢你们每个人都无法相信有这么多方法可以做到:D

5 个答案:

答案 0 :(得分:8)

我会将此签入移至单独的方法

public static bool ContainsDigit(int input, int digit)
{
    do
    {
        if (input % 10 == digit)
        {
            return true;
        }
        input /= 10;
    }
    while (input > 0);
    return false;
}

用法:

List<int> result = Allnumber.Where(x => ContainsDigit(x, 3)).ToList();

https://dotnetfiddle.net/2ZPNbM

一行中的相同方法

List<int> Allnumber = Enumerable.Range(0, 100).ToList();
List<int> result = Allnumber.Where(x => { do { if (x % 10 == 3) return true; } while ((x /= 10) > 0); return false; }).ToList();

执行(Allnumber with 1000000 number):

|------------------------------------------------------|
| User       | Method                   | Time         |
|------------|--------------------------+--------------|
| fubo       | ContainsDigit()          | 0,03 seconds |
| JamieC     | ToString().Contains("3") | 0,20 seconds |
| TheGeneral | WhereDigit()             | 0,10 seconds |
| TheGeneral | InternalRun()            | 0,04 seconds |
|------------------------------------------------------|

dotnetfiddle并不真正适用于benachmarking - 每次运行都有所不同可能因为dotnetfiddle的负载而且我只能使用100,000代替1,000,000数字但...... {{3 }}

答案 1 :(得分:3)

只是为了好玩,这是一个yield版本和IEnumerable扩展方法

public static class StupidExtensions
{
    public static IEnumerable<int> Digits(int input)
    {
        do yield return input % 10; while ((input /= 10) > 0);
    }

    public static IEnumerable<int> WhereDigit(this IEnumerable<int> source, int digit) 
              => source.Where(x => Digits(x).Contains(digit));
}

<强>用法

var result = Allnumber.WhereDigit(3);

Demo here

这里还有2个

protected override IEnumerable<int> InternalRun(IEnumerable<int> values, int digit)
{
   var ary = values.ToArray();
   var result = new List<int>();
   fixed (int* pAry = ary)
   {
      for (var p = pAry; p < pAry + ary.Length; p++)
         for (var d = *p; d > 0; d /= 10)
            if (d % 10 == digit){ result.Add(*p); break;}
   }  
}

protected override IEnumerable<int> InternalRun(IEnumerable<int> values, int digit)
{
   foreach (var val in values)
      for (var d = val; d > 0; d /= 10)
         if (d % 10 == digit)
            yield return val;
}

答案 2 :(得分:2)

  

我发现有Findall,Contain方法但不能用于int类型列表。

这些是可以使用的字符串方法,您只需将您的号码转换为字符串作为where子句的一部分

 List<int> HasThrees = (from number in Allnumber where number.ToString().Contains("3") select number).ToList();

但这是从解决此问题的最有效方法。它对小列表表现良好,但随着列表长度的增加逐渐变慢。

要获得更有效的解决方案,请查看其中一个答案,而不将数字转换为字符串。

答案 3 :(得分:2)

首先将Where子句中的所有数字转换为ToString的字符串,然后使用Contains获取包含数字3的所有数字的列表:

var result = Allnumber.Where(x => x.ToString().Contains("3")).ToList();

答案 4 :(得分:-1)

你需要检查余数是否为3除以10,即n%10 == 3。

IEnumerable<int> allThrees =
    from num in Allnumber
    where num%10 == 3
    select num;

此解决方案基于OP已包含的示例工作,在阅读评论后我意识到问题是关于所有3s如31,32。然后字符串操作可能是解决方案。