13 Replies - 717 Views - Last Post: 18 April 2019 - 08:40 AM Rate Topic: -----

#1 andrewsw   User is offline

  • quantum multiprover
  • member icon

Reputation: 6775
  • View blog
  • Posts: 27,938
  • Joined: 12-December 12

check and skip currency symbol

Posted 11 April 2019 - 12:58 AM

I have a string, price, which might be "20.00", "20.00" (it shouldn't be, but could also be $) or "20.00".

How would you convert the value to a decimal, ignoring the currency symbol?

I suppose I could read the first character and check if it is in $ (although I would prefer to discount ANY symbol) then Convert.ToDecimal the remaining values, but am optimistic there is a more straightforward way.

Is This A Good Question/Topic? 0
  • +

Replies To: check and skip currency symbol

#2 andrewsw   User is offline

  • quantum multiprover
  • member icon

Reputation: 6775
  • View blog
  • Posts: 27,938
  • Joined: 12-December 12

Re: check and skip currency symbol

Posted 11 April 2019 - 02:11 AM

I went ahead with this,

    // if there is a currency symbol, skip it
    if (Char.IsDigit(price, 0))
        UnitP = Convert.ToDecimal(price);
    else
        UnitP = Convert.ToDecimal(price.Substring(1));

I suppose there should be some additional verification that what remains is a valid number... but I won't worry about that now ;)
Was This Post Helpful? 1
  • +
  • -

#3 maceysoftware   User is offline

  • Member Title
  • member icon

Reputation: 370
  • View blog
  • Posts: 1,586
  • Joined: 07-September 13

Re: check and skip currency symbol

Posted 11 April 2019 - 06:10 AM

What about something like:

private string GetNumbersOnly(string input)
{
return new string(input.Where(ch => char.IsNumber(ch) || ch == '.').ToArray());
}

Would remove anything but numbers and decimal places. IsDigit would also work, not really sure the difference between the two.

Edit.

Could be a nice extension method, also got to think about that one user who will put 50£.

This post has been edited by maceysoftware: 11 April 2019 - 06:11 AM

Was This Post Helpful? 1
  • +
  • -

#4 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6818
  • View blog
  • Posts: 23,196
  • Joined: 05-May 12

Re: check and skip currency symbol

Posted 11 April 2019 - 06:12 AM

Why not use Decimal.Parse(price, NumberStyles.AllowCurrency) or its TryParseEquivalent? Furthermore, the NumberStyles also gives you options to handle decimal points and thousands separators in a culture appropriate way.
Was This Post Helpful? 2
  • +
  • -

#5 andrewsw   User is offline

  • quantum multiprover
  • member icon

Reputation: 6775
  • View blog
  • Posts: 27,938
  • Joined: 12-December 12

Re: check and skip currency symbol

Posted 11 April 2019 - 06:23 AM

Thank you both.

@maceysoftware We would have to be careful with IsNumber (and isDigit) as the string of characters (or some of them) may parse validation but the remaining string might still not be a number. MS explicitly encourages using the parse or convert methods.

@Skydiver, thanks, I hadn't picked up that Decimal.Parse has Allow Currency (the existing code was using Convert.ToDecimal).
Was This Post Helpful? 0
  • +
  • -

#6 andrewsw   User is offline

  • quantum multiprover
  • member icon

Reputation: 6775
  • View blog
  • Posts: 27,938
  • Joined: 12-December 12

Re: check and skip currency symbol

Posted 11 April 2019 - 06:44 AM

Mmm Could be an interesting challenge as a stack or something similar.

The first character can only be a currency symbol or digit.
Supposing a comma were submitted, it would be permitted only if the following 3 characters were digits, and rejected for any other character.
A dot must be followed only by two digits.

The dot and commas could be swapped.
Was This Post Helpful? 0
  • +
  • -

#7 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6818
  • View blog
  • Posts: 23,196
  • Joined: 05-May 12

Re: check and skip currency symbol

Posted 11 April 2019 - 07:01 AM

Thank God no sane country has decided to use a comma or a dot as their currency symbol. :)
Was This Post Helpful? 0
  • +
  • -

#8 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7419
  • View blog
  • Posts: 15,373
  • Joined: 16-October 07

Re: check and skip currency symbol

Posted 11 April 2019 - 08:04 AM

Very optimistic. :P

So, just to code golf the one you went with: Convert.ToDecimal(Char.IsDigit(price, 0) ? price : price.Substring(1))

The real question is how you want this thing to behave on failure. If you like exceptions thrown, you're good, but for myself I prefer a nice fail over default value. Also, this could be a job for Regex!

I'd go with:
private static Regex PriceMatcher = new Regex(@"^[$]?(\d+\.\d+)$", RegexOptions.Compiled);

public static decimal PriceToNum(string price, decimal defaultValue = 0) =>
    PriceToNum(PriceMatcher.Match(price), defaultValue);

private static decimal PriceToNum(Match m, decimal defaultValue) =>
    (m.Success && decimal.TryParse(m.Groups[1].Value, out decimal n)) ? n : defaultValue;



Now we allow for all kinds of badness and give you the ability to define more symbols, if you like.
Was This Post Helpful? 1
  • +
  • -

#9 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6818
  • View blog
  • Posts: 23,196
  • Joined: 05-May 12

Re: check and skip currency symbol

Posted 11 April 2019 - 08:38 AM

Lol! Looking at the source code for Convert.ToDecimal(), it just calls Decimal.Parse():
public static decimal ToDecimal(String value) {
    if (value == null)
        return 0m;
    return Decimal.Parse(value, CultureInfo.CurrentCulture);
}


and here's the implementations of Decimal.Parse() variants:
        public static Decimal Parse(String s) {
            return Number.ParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo);
        }
    
        public static Decimal Parse(String s, NumberStyles style) {
            NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
            return Number.ParseDecimal(s, style, NumberFormatInfo.CurrentInfo);
        }
 
        public static Decimal Parse(String s, IFormatProvider provider) {
            return Number.ParseDecimal(s, NumberStyles.Number, NumberFormatInfo.GetInstance(provider));
        }
    
        public static Decimal Parse(String s, NumberStyles style, IFormatProvider provider) {
            NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
            return Number.ParseDecimal(s, style, NumberFormatInfo.GetInstance(provider));
        }
    
        public static Boolean TryParse(String s, out Decimal result) {
            return Number.TryParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo, out result);
        }
 
        public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Decimal result) {
            NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
            return Number.TryParseDecimal(s, style, NumberFormatInfo.GetInstance(provider), out result);
        }


Was This Post Helpful? 1
  • +
  • -

#10 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 6818
  • View blog
  • Posts: 23,196
  • Joined: 05-May 12

Re: check and skip currency symbol

Posted 11 April 2019 - 04:51 PM

The downside of using the NumberStyles is that it can only handle one culture at a time. If you need something that can handle various currency symbols -- not necessarily the current culture -- then baavgai's approach seems to be the most straightforward.
Was This Post Helpful? 0
  • +
  • -

#11 Sheepings   User is offline

  • Senior Programmer
  • member icon

Reputation: 209
  • View blog
  • Posts: 1,182
  • Joined: 05-December 13

Re: check and skip currency symbol

Posted 17 April 2019 - 04:07 PM

View Postbaavgai, on 11 April 2019 - 03:04 PM, said:

private static Regex PriceMatcher = new Regex(@"^[£€$]?(\d+\.\d+)$", RegexOptions.Compiled);

Curious why you used Compiled over interpreted?

Compiled is set in stone and also used more memory. While it is recommended for iteration (on perhaps a large file), I would be inclined to use interpreted on one off executions, despite it being slower to execute. if it is something that is only going to be used once in a while; interpreted would suffice for me. Pre-compiled is not something I'd opt to use either, unless I had a regex or many regex which do not change, despite it has a faster execution time overall; so I believe.

I also think it is best to not use a static declaration or static method for regex.compiled. Troubleshooting could be problematic and any declared instance would need to be cleared manually. Does anyone else agree? Have said that; static would be Ok if you plan on forever reusing it, or if you want to run some thread safe executions. Just be sure not to use it where static methods require integration with anything that requires inheritance such as interfaces.

A read on performances :: https://blogs.msdn.m...avid-gutierrez/

This post has been edited by Sheepings: 17 April 2019 - 05:21 PM

Was This Post Helpful? 1
  • +
  • -

#12 baavgai   User is offline

  • Dreaming Coder
  • member icon


Reputation: 7419
  • View blog
  • Posts: 15,373
  • Joined: 16-October 07

Re: check and skip currency symbol

Posted 18 April 2019 - 04:06 AM

View PostSheepings, on 17 April 2019 - 06:07 PM, said:

Curious why you used Compiled over interpreted?

Because it's cool? ;)

From design perspective, I'm more concerned with systems scaling well than assuming a one off. My design assumptions are that this would not be use as a one off and is set in stone for the duration of the application.

If there were a number of these in a production system, I'd probably go with:
private static Lazy<Regex> PriceMatcher = new Lazy<Regex>(() => new Regex(@"^[$]?(\d+\.\d+)$", RegexOptions.Compiled));



However, your point is well taken: the developer should always consider their requirements when using their tools.
Was This Post Helpful? 0
  • +
  • -

#13 DarenR   User is offline

  • D.I.C Lover

Reputation: 601
  • View blog
  • Posts: 3,932
  • Joined: 12-January 10

Re: check and skip currency symbol

Posted 18 April 2019 - 07:48 AM

im curious but why would you store monetary values with symbols?
Was This Post Helpful? 0
  • +
  • -

#14 andrewsw   User is offline

  • quantum multiprover
  • member icon

Reputation: 6775
  • View blog
  • Posts: 27,938
  • Joined: 12-December 12

Re: check and skip currency symbol

Posted 18 April 2019 - 08:40 AM

Not my choice. The whole system is botched together.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1