1

I need to create a method that takes in a string of numbers - for example, 174709580098747434. It then needs to be formatted as chunks of three and returned in an array - for example, {174, 709, 580, 098,747,434}.

Here is what I have so far. I dont think this is doing the right job. Also it wont be useful if i have a very large number like above.

I am very new to C# and just a beginner!

using System;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            string ques = "17470958834";
            Console.WriteLine(Chunk(ques));
        }
        public static string Chunk(string num)
        {
            // long inInt = Convert.ToInt64(num);
            string ans = "";
            for (int i = 0; i < num.Length; i += 3)
            {
                if (i == 2)
                {
                    ans.Insert(2, "-");
                }

                else if (i == 5)
                {
                    ans.Insert(5, "-");
                }
                else if (i == 8)
                {
                    ans.Insert(8, "-");
                }
                else if (i == 11)
                {
                    ans.Insert(11, "-");
                }
            }

            return ans;
        }
    }
}
Sisir
  • 4,584
  • 4
  • 26
  • 37
  • You want to get the bytes not strings : ulong input = 174709580098747434; byte[] output = BitConverter.GetBytes(input); – jdweng Jul 27 '20 at 11:17
  • OP: Your `if` clauses will never come true, because your `for` will iterate `i` to be 0, 3, 6, 9, ... – Fildor Jul 27 '20 at 11:21
  • What shall be the output if the length of the input string is not dividable by 3? – Fildor Jul 27 '20 at 11:23
  • 2
    What should be the result for the input of 12? 1234? 12.345? -1234? 0012? – mjwills Jul 27 '20 at 11:24
  • "and returned in an array" why does your method `Chunk` return a `string` ? because `Console.WriteLine` needs a `string` as parameter? – Mong Zhu Jul 27 '20 at 11:30
  • Go with the answer posted in the link by Orel Eraki. – Krystian Borysewicz Jul 27 '20 at 11:30
  • what you need to know here is the [modulo operator or remainder operator](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/arithmetic-operators#remainder-operator-) with it you can test whether the index is devideable by 3. This can save you a lot of if clauses – Mong Zhu Jul 27 '20 at 11:33
  • 1
    "I am very new to C# and just a beginner!" if this is true, then I would strongly advise against the solution posted by Orel. Your exercise is designed for a simply purpose: namely to force you to undergo the "painfull" process of thinking yourself through the problem and through a possible algorithm. I would advise you to try and solve this problem first with pen and paper. write down the algorithm in human language, and then try to translate it into code. You have solved almost the entire problem. – Mong Zhu Jul 27 '20 at 11:57
  • here are some tips: 1) use an extenable collection like `List` to collect your chunks. 2) you already iterate through the string in steps of 3, put this number into a variable and use it. 3) research "C# extract part of string" and you will find a method that does exactly that. – Mong Zhu Jul 27 '20 at 12:00

3 Answers3

1

If you NuGet the "System.Interactive" extensions to get the Buffer operator then you can do this:

var number = "174709580098747434";
var output =
    String.Join(
        " ",
        number //174709580098747434 - string
            .Reverse() //434747890085907471 - char array
            .Buffer(3) //434 747 890 085 907 471 - array of char array
            .Select(x => String.Concat(x.Reverse())) //434 747 098 580 709 174 - string array
            .Reverse()); //174 709 580 098 747 434 - string

That gives me 174 709 580 098 747 434.

Without Buffer you can use the slightly more ugly version:

var output =
    String.Join(
        " ",
        number
            .Reverse()
            .Select((x, n) => (x, n))
            .GroupBy(z => z.n / 3)
            .Select(z => z.Select(y => y.x))
            .Select(x => String.Concat(x.Reverse()))
            .Reverse());
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0

It should be more simpler for a beginner and should be thought provoking. Follow the below technique:

string value = "174709580098747434";
int chunk = 3;
int length = value.Length;
for (int i = 0; i < length; i += chunk)
{
    if (i + chunk > length) chunk = length - i;
    Console.WriteLine(value.Substring(i, chunk));
}
Console.ReadLine();
Sh.Imran
  • 1,035
  • 7
  • 13
  • Can you elaborate on the simplicity and thought provoking nature of this solution? – Enigmativity Jul 27 '20 at 12:37
  • Simple solution for a beginner and looping to build logic. Otherwise there is much neat and short solution provided by @Orel Eraki in the first comment. – Sh.Imran Jul 27 '20 at 12:46
-1

I hope, below code will solve your problem.

public static  string[] Chunk(string number)
{
    int count = (number.Length / 3)+(number.Length % 3 > 0 ? 1 : 0);
    string[] result = new string[count];
    for (int i = 0; i < count; i++)
    {
        result[i] = number.Substring(i*3, ((i+1) * 3) < number.Length ? 3 : number.Length - (i * 3));
    }
    return result;
}

If you want, you can even generalize it like below:

///number is string value
///splitStringCount is count which you want your string to get splitted.
private string[] Chunk(string number, int splitStringCount = 3)
    {
        int count = (number.Length / splitStringCount) +(number.Length % splitStringCount > 0 ? 1 : 0);
        string[] result = new string[count];
        for (int i = 0; i < count; i++)
        {
            result[i] = number.Substring(i* splitStringCount, ((i+1) * splitStringCount) < number.Length ? splitStringCount : number.Length - (i * splitStringCount));
        }
        return result;
    }

And if you want only 3 digit number in return array then check below code:

Call this method like below:

Chunk("174709580098747434");

And method logic is give below:

public static string[] Chunk(string number, int splitStringCount = 3)
    {
        int count = (number.Length / splitStringCount);
        string[] result = new string[count];
        for (int i = 0; i < count; i++)
        {
            result[i] = number.Substring(i* splitStringCount, splitStringCount);
        }
        return result;
    }
Rajeev Kumar
  • 371
  • 2
  • 9
  • Can someone comment here for the down cast? – Rajeev Kumar Jul 27 '20 at 11:41
  • 1
    "Can someone comment here for the down cast?" No, I did not cast the vote, but I can comment on your answer. It has a lot of (partly cryptic) code and no explanation to it. Your answer does not explain why the problem arose in the first place or what is wrong with the code OP had posted. It neither explains what your code does and how it actually is meant to solve OP's problem. My best guess is that these are partly the reasons for the downvote. At least for me it would be, But I rather write comments than down vote – Mong Zhu Jul 27 '20 at 11:45