Willy David Jr
Willy David Jr

Reputation: 9131

Get Group of Numbers on a String

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

Answers (7)

Chinito
Chinito

Reputation: 1175

Try this:

int[] strArr = strFood.ToCharArray().Where(x=> Char.IsDigit(x)).Select(y => Convert.ToInt32(y.ToString())).ToArray();

Upvotes: 0

Steve Ford
Steve Ford

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

shA.t
shA.t

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

Maksim Simkin
Maksim Simkin

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

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

Dmitrii Bychenko
Dmitrii Bychenko

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

Alex
Alex

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

Related Questions