Reputation: 9131
I have a string which consists of numbers and letters like the example below:
string strFood = "123d 4hello12";
What I want to accomplish is get all the group of numbers which is 123, 4, and 12.
I am trying to do this via LinQ but I am not getting the array results since my plan is to get the array then add them altogether which is 123 + 4 + 12 and the result is 139.
This is what I tried so far but this doesn't result to group of string or integer:
string[] strArr =
strFood .GroupBy(y => Char.IsDigit(y)).Select(y => y.ToString()).ToArray();
I also tried this one but this returns all the number in one string:
var foo = from a in strFood .ToCharArray() where Char.IsDigit(a) == true select a;
Any help would be appreciated.
Upvotes: 0
Views: 1365
Reputation: 1175
Try this:
int[] strArr = strFood.ToCharArray().Where(x=> Char.IsDigit(x)).Select(y => Convert.ToInt32(y.ToString())).ToArray();
Upvotes: 0
Reputation: 7753
I tried using an approach using Split
and Join
.
First i use Linq Select
to replace non digits with a ',':
strFood.Select(ch => (Char.IsDigit(ch)) ? ch : ',');
I then use Join
to turn this back into a string of the form "123,,4,,,,,12", I then Split
this on "," and filter out values (using Where
) which have an empty string, I then convert the string into a number e.g. "123" becomes 123 and I sum the array.
Putting this all together becomes:
var Sum = String.Join("",(strFood.Select(c => (Char.IsDigit(c)) ? c : ',')))
.Split(',').Where(c => c != "").Select(c => int.Parse(c)).Sum();
Here's a slightly shorter version using Concat:
var Sum = String.Concat(strFood.Select(ch => (Char.IsDigit(ch)) ? ch : ','))
.Split(',').Where(c => c != "").Select(c => int.Parse(c)).Sum();
This gives a result of 139
Upvotes: 0
Reputation: 16958
Just to add decimal numbers in summation, you can use this regex instead:
var str = "123d 4hello12and0.2plus.1and-1and2+8.but 1....1 a.b";
// ^^^ ^ ^^ ^^^ ^^ ^^ ^ ^ ^ ^^
var s = Regex
.Matches(str, @"-?([0-9]+|[0-9]*\.[0-9]+)")
.OfType<Match>()
.Sum(c=> double.Parse(c.Value, CultureInfo.InvariantCulture));
Result will be:
Count = 11
[0]: {123}
[1]: {4}
[2]: {12}
[3]: {0}
[4]: {.2}
[5]: {.1}
[6]: {-1}
[7]: {2}
[8]: {8}
[9]: {1}
[10]: {.1}
Sum = 149.39999999999998 //~= 149.4
Upvotes: 1
Reputation: 9679
You could split your string to integers collection:
string strFood = "123d 4hello12";
var integers = new Regex(@"\D").Split(strFood)
.Where(x=>!string.IsNullOrWhiteSpace(x))
.Select(x=>int.Parse(x));
and after that sum it with:
var sum = integers.Sum(); // Result : 139
Edit after comment of @Dmitry Bychenko: with some characters, such as persian digits that won't work. Solution: either use
new Regex(@"[^0-9+]")
or
new Regex(@"\D", RegexOptions.ECMAScript)
Upvotes: 1
Reputation: 900
Why don't you use a simple regular expression?
string input = "123d 4hello12";
int sum = System.Text.RegularExpressions.Regex.Matches(input, @"\d+").Cast<System.Text.RegularExpressions.Match>().Sum(m => Convert.ToInt32(m.Value));
Upvotes: 0
Reputation: 186668
I suggest using regular expressions to find all groups (matches) with aggregation via Linq:
string strFood = "123d 4hello12";
var sum = Regex
.Matches(strFood, "[0-9]+") // groups of integer numbers
.OfType<Match>()
.Select(match => int.Parse(match.Value)) // treat each group as integer
.Sum(); // sum up
If you want to obtain an array (and sum up later):
int[] result = Regex
.Matches(strFood, "[0-9]+") // groups of integer numbers
.OfType<Match>()
.Select(match => int.Parse(match.Value))
.ToArray();
...
var sum = result.Sum();
Upvotes: 5
Reputation: 3889
var yourSum = strFood.Where(x=>Char.IsDigit(x)).Select(x=>Convert.ToInt32(x)).Sum()
This will give you the sum of all numbers in your string.
If you want just an IEnumerable of ints remove the Sum()
from the end
Upvotes: 0