Erdogan CEVHER
Erdogan CEVHER

Reputation: 1619

A patterned irregular splitting of a number into many parts of its digits in C#?

Whenever I am given a 11-digit number (like 12345678901, 82344678971 etc.), I want to partition it into 4 parts as 5digits-4digits-1digit-1digit always. So:
12345678901 -> 12345 6789 0 1
82344674971 -> 82344 6749 7 1

I saw a similar question in SOF but it uses regular blocks; namely same number of digits: Splitting a string / number every Nth Character / Number?

I want a function that will take any 11-digit (long) integer as parameter, and will return as the above way; from where I could be able to get any block I want: For example, SplitInParts(1) will return 12345; SplitInParts(2) will return 6789; SplitInParts(3) will return 0; SplitInParts(4) will return 1. Similarly for 82344674971: 82344, 6749, 7, 1 respectively.

Being a novice in C#, I could not achieve how to perform the above via C#.

Upvotes: 2

Views: 132

Answers (6)

SWeko
SWeko

Reputation: 30902

If you have it an integer, you can get the decimal digits out using something like:

List<int> GetDigits(long number){
   var result = new List<int>();
   while (number != 0){
       result.Insert(0, (int)(number %10));
       number /=10;
   }
   return result;
}

This uses repeated division and modulo 10 to get the singular digits into a List<int>

Now, from that you can get your formatted string in a number of ways, e.g. and using string.Join (framework 4.5 and above) on them, like:

var digits = GetDigits(12345678901);
var part1 = string.Join("",digits.Take(5));
var part2 = string.Join("",digits.Skip(5).Take(4));
var part3 = string.Join("",digits.Skip(9).Take(1));
var part4 = string.Join("",digits.Skip(10).Take(1));

This solution is a tad slower (albeit more fun) than the solutions that just use number.ToString(), so if you just need the format, go with that. Use this if you actually need the digits themselves.

Upvotes: 3

Calum
Calum

Reputation: 1889

This is an extension method on long that works in a similar manner to the example you provided and I think it's quite readable although it might not perform as well as other solutions.

public static class LongExtensions
{
    public static int SplitIntoIrregularParts(this long longNumber, int partIndexToReturn)
    {
        int[] blocks = string.Format("{0:##### #### # #}", longNumber).Split(' ').Select(x => int.Parse(x)).ToArray();
        return blocks[partIndexToReturn];
    }
}

Upvotes: 3

Rick
Rick

Reputation: 841

Depending on how you want to handle numbers shorter than 11 digits, then this might be a robust option. It copes with any number of digits, adding spaces if possible.

But you can use something simpler if you just need it to fail if the number of digits is less than 11.

var t = InsertGaps(12345678912);


private string InsertGaps(long value) 
{
   var result = value.ToString();
   result = InsertGap(result, 5);
   result = InsertGap(result, 10);
   result = InsertGap(result, 12);
   return result;
}

private string InsertGap(string value, int index) 
{
   if (value.Length > index) 
   {
      return value.Insert(index, " ");
   }
   return value;
}

Upvotes: 0

lintmouse
lintmouse

Reputation: 5119

Here are a few options:

string id = 82344678971.ToString();

string parsed = Regex.Replace(id, @"(\d{5})(\d{4})(\d{1})(\d{1})", @"$1 $2 $3 $4");
string parsed2 = String.Join(" ", new string[] { 
    id.Substring(0, 5), 
    id.Substring(5, 4), 
    id.Substring(9, 1), 
    id.Substring(10, 1) 
});

char[] chars = id.ToCharArray();

string parsed3 = String.Join(" ", new string[] { 
    new String(chars, 0, 5), 
    new String(chars, 5, 4), 
    new String(chars, 9, 1), 
    new String(chars, 10, 1) 
});

Upvotes: 1

Lorenzo
Lorenzo

Reputation: 3387

Use this function where I use substring.

 private string getMySubString(long value, int splitPart)
  {
     string str = value.ToString();

     if (str.Length != 11) return "invalid number lenght";

     string sub1 = str.Substring(0, 5);
     string sub2 = str.Substring(5, 4);
     string sub3 = str.Substring(9, 1);
     string sub4 = str.Substring(10, 1);

     switch (splitPart)
     {
        case 1:
           return sub1;
        case 2:
           return sub2;
        case 3:
           return sub3;
        case 4:
           return sub4;
        default:
           return "Invalid part number";
     }
  }

Use "value" as original value that you want split and "splitPart" as number of part you want extract. I hope this is what you are asking If you want , then you can convert the returned string into an Integer

Upvotes: 1

Moho
Moho

Reputation: 16543

Use the Take and Skip extension methods of Enumerable on a character array

Upvotes: 1

Related Questions