Jungmin Koo
Jungmin Koo

Reputation: 77

C# How can I pick up numbers that contains x number from 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));

I want to make a new list which includes 3 from Allnumber list. It should be containing all the number that has 3(3, 13, 23, 33, 34, 36, 39, 43, 53...). Anyway to pick up only 3s? I found out there are Findall, Contain methods but cant use it for int type list. THANK YOU EVERYONE cant believe that there are so many ways to do it :D

Upvotes: 4

Views: 795

Answers (5)

fubo
fubo

Reputation: 45947

I would move this check in to a separate method

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

usage:

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

https://dotnetfiddle.net/2ZPNbM


Same approach in one line

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();

Performace (Allnumber with 1000000 numbers):

|------------------------------------------------------|
| 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 doesn't really work with benachmarking - it varies a bit each run probably because of the load of dotnetfiddle and I can only use 100,000 instead of 1,000,000 numbers but ... https://dotnetfiddle.net/pqCx2J

Upvotes: 8

TheGeneral
TheGeneral

Reputation: 81493

Just for fun, here is a yield version and IEnumerable extension method

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));
}

Usage

var result = Allnumber.WhereDigit(3);

Demo here


Here are 2 more

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;
}

Upvotes: 3

Jamiec
Jamiec

Reputation: 136104

I found out there are Findall, Contain methods but cant use it for int type list.

These are string methods, which can can use, you just need to convert your number to a string as part of the where clause

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

But this is far from the most efficient way to solve this problem. It will perform fine for small lists, but get progressively slower as the length of your list increases.

For a more efficient solution look at one of the answers that do this without converting the numbers to a string.

Upvotes: 2

Slaven Tojić
Slaven Tojić

Reputation: 3014

First convert all numbers in the Where clause to strings with ToString and then use Contains to get the list of all the numbers that contain the number 3:

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

Upvotes: 2

PM.
PM.

Reputation: 1721

You simply need to check if remainder is 3 after dividing it by 10 i.e. n%10 == 3.

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

This solution works on the based of examples OP has included, after reading a comment I realize if question is about all 3s like 31,32. Then string manipulation might be the solution.

Upvotes: -1

Related Questions