How to split string number into separate integers - c#

I'm new in C# and programming at all, and I face the following problem.
How to split a given number, which I recieve as a string, to array of integers in console application?
For example: My input is 41234 and I want to turn it to array of "4", "1", "2", "3" and "4".
I've tried to use standard
Console.ReadLine().Split().Select(int.Parse).ToArray();
But it sets the whole number as content of the first index of the array, does not splits it.
I've also tried to use char[] array, but in some cases it returns the ASCII value of the char, not the value it represents.

If you want to return each character as an integer, you can just treat the string as an IEnumerable<char> (which it is) and you can use a couple of static methods on the char class:
char.IsNumber will return true if the character is a number
char.GetNumericValue will return the numeric value of the character (or -1 for non-numeric characters)
For example:
int[] numbers = "123456_ABC"
.Where(char.IsNumber) // This is optional if you know they're all numbers
.Select(c => (int) char.GetNumericValue(c)) // cast here since this returns a double
.ToArray();
Alternatively, since we know non-numeric characters get a -1 value from GetNumericValue, we can do:
int[] numbers = "123456_ABC"
.Select(c => (int) char.GetNumericValue(c)) // cast here since this returns a double
.Where(value => value != -1) // This is optional if you know they're all numbers
.ToArray();
In both cases above, numbers becomes: {1, 2, 3, 4, 5, 6}

but in some cases it returns the ASCII value of the char, not the value it represents.
It always does that (a string is a sequence of char), but if you're only dealing with integers via characters in the range '0'-'9', you can fix that via subtraction:
int[] values = s.Select(c => (int)(c - '0')).ToArray();

String.Split uses whitespace characters as the default separators. This means that String.Split() will split along spaces and newlines. It won't return individual characters.
This expression :
var ints = "1\n2 345".Split();
Will return :
1 2 345
A string is an IEnumerable<char> which means you can process individual characters. A Char is essentially an Int32 and digits are ordered. This means you can get their values by subtracting the value of 0:
var ints = "12345".Select(c=>c-'0').ToArray();
Or even :
var sum="12345".Select(c=>c-'0').Sum();
Debug.Assert(sum==15);

This Code snapshot will replace all character except numeric to blank and gives you only int array.
string a = "1344te12we3ta";
Regex rgx = new Regex("\\D+");
string result = rgx.Replace(a, "");
int[] intA = Array.ConvertAll(result.ToCharArray(), c => (int)Char.GetNumericValue(c));

There is much solution in C# for this
int[] values = "41234".ToArray().Select(c=> (int)char.GetNumericValue(c)).ToArray();

Related

Remove non numeric characters from string and cast numbers as an int into an array

I have a string: "ABD1254AGSHF56984,5845fhfhjekf!54685" and I want to loop through each character in this string and find any non numeric character and remove the characters until the next numeric character. i.e. remove all the non numeric characters from my string but these should be an indiciator that the numbers are seperate.
Output as an integer array:
1254
56984
5845
54685
These should be put into an array and converted as integers.
My attempt below but this just puts all the numbers as one rather than splitting them up based on the non numeric characters:
var input = "ABD1254AGSHF56984,5845fhfhjekf!54685";
var numeric = new String(input.Where(char.IsDigit).ToArray());
//This is the output of my attempt: 125456984584554685
You can use Regex to split up your numbers and letters,
string line = "ABD1254AGSHF56984,5845fhfhjekf!54685";
// This splits up big string into a collection of strings until anything other than a character is seen.
var words = Regex.Matches(line, #"[a-zA-Z]+");
// This gives you a collection of numbers...
var numbers = Regex.Matches(line, #"[0-9]+");
foreach (Match number in numbers)
{
Console.WriteLine(number.Value);
}
// prints
1254
56984
5845
54685
Regex Documentation should be read before implementation for better understanding.
If you can use the .NET Framework, there's a great class called System.Text.RegularExpressions.Regex that can be your new best friend.
var input = "ABD1254AGSHF56984,5845fhfhjekf!54685";
var numeric = Regex.Replace(input, #"[^\d]+", "\n").Trim();
What the above method is doing is it is looking for one or more non-decimal characters and replacing it with a carriage return (\n). The Trim() ensures that it removes any leading or trailing carriage returns.
Output:
1254
56984
5845
54685
There is no need for black magic to solve such a problem. You can solve it with a for-loop. It's been there since the begining of programming and is designed for such stuff ;)
check IF the character is a number. Then start collecting the digits
ELSE you hit a boundary and you can convert the collected digits to a single int and clear your temporal digit storage:
the only tricky thing here is that if you have a number at the end (where there is no non-numeric character as boundary afterwards) you need to check whether you hit the final boundary.
var input = "ABD1254AGSHF56984,5845fhfhjekf!54685";
string separateNumber = "";
List<int> collection = new List<int>();
for (int i = 0; i < input.Length; i++)
{
if (Char.IsDigit(input[i]))
{
separateNumber += input[i];
if (i == input.Length -1) // ensures that the last number is caught
{
collection.Add(Convert.ToInt32(separateNumber));
}
}
else if (string.IsNullOrEmpty(separateNumber) == false)
{
collection.Add(Convert.ToInt32(separateNumber));
separateNumber = "";
}
}
You're almost there, all you need is to not pass the results of your LINQ query to a new String() instance. This should work:
var numeric = input.Where(char.IsDigit).ToArray();

Get a number and string from string

I have a kinda simple problem, but I want to solve it in the best way possible. Basically, I have a string in this kind of format: <some letters><some numbers>, i.e. q1 or qwe12. What I want to do is get two strings from that (then I can convert the number part to an integer, or not, whatever). The first one being the "string part" of the given string, so i.e. qwe and the second one would be the "number part", so 12. And there won't be a situation where the numbers and letters are being mixed up, like qw1e2.
Of course, I know, that I can use a StringBuilder and then go with a for loop and check every character if it is a digit or a letter. Easy. But I think it is not a really clear solution, so I am asking you is there a way, a built-in method or something like this, to do this in 1-3 lines? Or just without using a loop?
You can use a regular expression with named groups to identify the different parts of the string you are interested in.
For example:
string input = "qew123";
var match = Regex.Match(input, "(?<letters>[a-zA-Z]+)(?<numbers>[0-9]+)");
if (match.Success)
{
Console.WriteLine(match.Groups["letters"]);
Console.WriteLine(match.Groups["numbers"]);
}
You can try Linq as an alternative to regular expressions:
string source = "qwe12";
string letters = string.Concat(source.TakeWhile(c => c < '0' || c > '9'));
string digits = string.Concat(source.SkipWhile(c => c < '0' || c > '9'));
You can use the Where() extension method from System.Linq library (https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.where), to filter only chars that are digit (number), and convert the resulting IEnumerable that contains all the digits to an array of chars, that can be used to create a new string:
string source = "qwe12";
string stringPart = new string(source.Where(c => !Char.IsDigit(c)).ToArray());
string numberPart = new string(source.Where(Char.IsDigit).ToArray());
MessageBox.Show($"String part: '{stringPart}', Number part: '{numberPart}'");
Source:
https://stackoverflow.com/a/15669520/8133067
if possible add a space between the letters and numbers (q 3, zet 64 etc.) and use string.split
otherwise, use the for loop, it isn't that hard
You can test as part of an aggregation:
var z = "qwe12345";
var b = z.Aggregate(new []{"", ""}, (acc, s) => {
if (Char.IsDigit(s)) {
acc[1] += s;
} else {
acc[0] += s;
}
return acc;
});
Assert.Equal(new [] {"qwe", "12345"}, b);

how to split a string based on integers occurrence? [duplicate]

This question already has answers here:
How to get the last five characters of a string using Substring() in C#?
(12 answers)
Closed 4 years ago.
If a string that contains integers and I want to split it based on integers occurrence. how to do that?
string test= "a b cdf 7654321;
then I want to store the integer and all words before it, like this
string stringBefore="";
// the integer will be last item
string integer="";
Note:
in my case the integer always will be 7 digits
You can use Regex.Split with a capture group to return the delimiter:
var ans = Regex.Split(test, #"("\d{7})");
If the number is at the end of the string, this will return an extra empty string. If you know it is always at the end of the string, you can split on its occurrence:
var ans = Regex.Split(test, #"(?=\d{7})");
According to your comments the integer is always 7 digits and it is always the last item of the string.
In that case, just use Substring()
string test = "a b cdf 7654321";
string stringBefore = test.Substring(0, test.Length - 7);
string integer = test.Substring(test.Length - 7);
Substring just makes a string based on a portion of your original string.
EDIT
I was a little surprised to find there wasn't a built in way to easily split a string in to two strings based on an index (maybe I missed it). I came up with a LINQ extension method that achieves what I was trying to do, maybe you will find it useful:
public static string[] SplitString(this string input, int index)
{
if(index < 0 || input.Length < index)
throw new IndexOutOfRangeException();
return new string[]
{
String.Concat(input.Take(input.Length - index)),
String.Concat(input.Skip(input.Length - index))
};
}
I think I would rather use a ValueTuple if using C# 7, but string array would work too.
Fiddle for everything here

Replacing specific parts of a string in an array

I'm pretty familiar with finding and replacing things in an array, but I'm having trouble finding out how to replace specific parts of a string. For instance, say the first item in my array is a string of sixteen random numbers like 1786549809654768. How would I go about replacing the first twelve characters with x's for example?
Because string can be translated to and from an array of char you could easily transform your problem into replace things in an array problem:
char[] characters = input.ToCharArray();
// do your replace logic here
string result = new string(characters);
Or you could use Substring. Assuming n is number of characters you want to replace from the beginning or the string:
string result = new string('x', n) + input.Substring(n);
You can use Linq:
String test = "1234123412341234";
string output = new String(test.Select((c, index) => index < 12 ? 'x' : c).ToArray());
Console.WriteLine(output);
//xxxxxxxxxxxx1234

C# subscript string including variable

I know that in C# to write subscript, I should use Unicode
for example
I want to write H2O , I should write
String str = "H"+"\x2082"+ "O"
But I want to put variable type of int instead of 2 in formula
How can I create a string with variable, which is written in subscript?
In Unicode, the subscript digits are assigned consecutive codepoints, ranging from U+2080 to U+2089. Thus, if you take the Unicode character for subscript 0 – namely, '₀' – then you can obtain the subscript character for any other digit by adding its numeric value to the former's codepoint.
If your integer will only consist of a single digit:
int num = 3;
char subscript = (char)('₀' + num); // '₃'
If your integer may consist of any number of digits, then you can apply the same addition to each of its digits individually. The easiest way of enumerating an integer's digits is by converting it to a string, and using the LINQ Select operator to get the individual characters. Then, you subtract '0' from each character to get the digit's numeric value, and add it to '₀' as described above. The code below assumes that num is non-negative.
int num = 351;
var chars = num.ToString().Select(c => (char)('₀' + c - '0'));
string subscript = new string(chars.ToArray()); // "₃₅₁"
This wikipedia article shows you all the unicode codes for super and subscript symbols.
You can simply create a method which maps these:
public string GetSubScriptNumber(int i)
{
// get the code as needed
}
I will give a few hints to help you along:
Unfortunately you can't just do return "\x208" + i so you'll need to do a switch for the numbers 0-9 or add the integer to "\x2080".
If you only need 0-9 then do some error checking that the input is in that range and throw an ArgumentOutOfRangeException
If you need all ints then you may find it easier splitting it up into each digit and getting a char for each of those - watch out for negative numbers but there is a character for subscript minus sign too!
To include the number in your string, you can use something like String.Format:
String.Format("H{0}O", GetSubScriptNumber(i))
Try to escape it
String str = "H" + "\\x2082" + "O";
or use verbose strings
String str = "H" + #"\x2082" + "O";
Maybe we don't understand your question. Several of the answers above seem correct. Does this work?
static string GetSubscript(int value)
{
StringBuilder returnValue = new StringBuilder();
foreach (char digit in value.ToString())
returnValue.Append((char)(digit - '0' + '₀'));
return returnValue.ToString();
}
string waterFormula = "H" + GetSubscript(2) + "0" // H₂O
string methaneFormula = "CH" + GetSubscript(4) // CH₄

Categories

Resources