Get number from end of name

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andrus

    Get number from end of name

    I need to create function

    static int ItemNumber(stri ng itemName)

    which returns number from end of name

    ItemNumber("Ite m1") returns 1
    ItemNumber("Oth er1") returns 1
    ItemNumber("Ite m123") returns 123


    etc.
    How to create this ?

    Andrus.

  • zacks@construction-imaging.com

    #2
    Re: Get number from end of name

    On Aug 7, 12:09 pm, "Andrus" <kobrule...@hot .eewrote:
    I need to create function  
    >
    static int ItemNumber(stri ng itemName)
    >
    which returns number from end of name
    >
    ItemNumber("Ite m1")  returns  1
    ItemNumber("Oth er1")  returns  1
    ItemNumber("Ite m123")  returns  123
    >
    etc.
    How to create this ?
    >
    Andrus.
    Loop through the string with the .Substring method specifying one
    character at at time. Try to convert the character to a number in a
    Try/Catch block. When the function is successful, then from that index
    position on is the number, and you can pick it off with
    another .Substring call.

    Comment

    • Jon Skeet [C# MVP]

      #3
      Re: Get number from end of name

      On Aug 7, 5:16 pm, za...@construct ion-imaging.com wrote:
      Loop through the string with the .Substring method specifying one
      character at at time.
      There's no point in creating loads of strings for no reason. Using the
      indexer returns a char:

      char c = text[i];
      Try to convert the character to a number in a
      Try/Catch block.
      Ick no. Use Character.IsDig it - then you're not using exceptions for
      flow control.
      When the function is successful, then from that index
      position on is the number, and you can pick it off with
      another .Substring call.
      No, that would fail on "foo5bar10" . We need to work back from the end.
      I would suggest something like:

      public static int ParseNumberAtEn d(string text)
      {
      for (int i = text.Length-1; i >= 0; i--)
      {
      if (!Character.IsD igit(text[i]))
      {
      if (i == text.Length - 1)
      {
      throw new ArgumentExcepti on("No digits at end");
      }
      string digits = text.Substring( i+1);
      return int.Parse(digit s);
      }
      }
      // Text is entirely made of digits!
      return int.Parse(text) ;
      }

      Alternatively, Andrus could use a regex of something like @"\d
      +^" (Possibly $ instead of ^ - I can never remember which way round
      they go.)

      Jon

      Comment

      • Ben Voigt [C++ MVP]

        #4
        Re: Get number from end of name

        Alternatively, Andrus could use a regex of something like @"\d
        +^" (Possibly $ instead of ^ - I can never remember which way round
        they go.)
        $ in this case, to anchor the end.
        ^ anchors the beginning.


        LastIndexOfAny might also be a reasonable solution, though I would expect
        Char.IsDigit to be faster.
        >
        Jon

        Comment

        • jake

          #5
          Re: Get number from end of name

          Along the same lines as Jon's reply, here is a fun way if you are
          using Framework 3.5:

          int.Parse("0" +
          item.Substring( Array.LastIndex Of<char>(item.T oCharArray(),
          item.ToCharArra y().LastOrDefau lt<char>(c =!Char.IsDigit( c))) + 1))

          Long line, but nice trick. Just an FYI.
          jake


          On Aug 7, 12:28 pm, "Jon Skeet [C# MVP]" <sk...@pobox.co mwrote:
          On Aug 7, 5:16 pm, za...@construct ion-imaging.com wrote:
          >
          Loop through the string with the .Substring method specifying one
          character at at time.
          >
          There's no point in creating loads of strings for no reason. Using the
          indexer returns a char:
          >
          char c = text[i];
          >
          Try to convert the character to a number in a
          Try/Catch block.
          >
          Ick no. Use Character.IsDig it - then you're not using exceptions for
          flow control.
          >
          When the function is successful, then from that index
          position on is the number, and you can pick it off with
          another .Substring call.
          >
          No, that would fail on "foo5bar10" . We need to work back from the end.
          I would suggest something like:
          >
          public static int ParseNumberAtEn d(string text)
          {
          for (int i = text.Length-1; i >= 0; i--)
          {
          if (!Character.IsD igit(text[i]))
          {
          if (i == text.Length - 1)
          {
          throw new ArgumentExcepti on("No digits at end");
          }
          string digits = text.Substring( i+1);
          return int.Parse(digit s);
          }
          }
          // Text is entirely made of digits!
          return int.Parse(text) ;
          >
          }
          >
          Alternatively, Andrus could use a regex of something like @"\d
          +^" (Possibly $ instead of ^ - I can never remember which way round
          they go.)
          >
          Jon

          Comment

          • Peter Duniho

            #6
            Re: Get number from end of name

            On Thu, 07 Aug 2008 10:05:18 -0700, Ben Voigt [C++ MVP]
            <rbv@nospam.nos pamwrote:
            >Alternativel y, Andrus could use a regex of something like @"\d
            >+^" (Possibly $ instead of ^ - I can never remember which way round
            >they go.)
            >
            $ in this case, to anchor the end.
            ^ anchors the beginning.
            >
            >
            LastIndexOfAny might also be a reasonable solution, though I would expect
            Char.IsDigit to be faster.
            Of course, if faster was the priority, calling Parse() is probably not the
            preferred solution anyway. Instead, one would just scan once from the end
            to find the start of the numeric string, and then go forward again,
            accumulating each digit and multiplying by 10 with each new one before
            adding the current digit. In other words, basically the same as what
            Jon's code does, but combining the substring extraction with the parsing,
            and doing it all in the same method rather than calling into the classes
            (and without instantiating an intermediate string). For example:

            public static int ParseNumberAtEn d(string text)
            {
            int i = text.Length;
            int result = 0;

            while (--i >= 0 && Character.IsDig it(text[i])) { }

            if (i == text.Length - 1)
            {
            throw new ArgumentExcepti on("No digits at end");
            }

            while (++i < text.Length)
            {
            result = result * 10 + text[i] - '0';
            }

            return result;
            }

            For maintainability , I like the RegEx suggestion. It keeps all the
            looping/substring mechanics hidden from view, leaving just the semantics
            of "parse the number at the end of the string".

            I think using LastIndexOfAny( ) is a reasonable alternative to RegEx, if
            one finds the RegEx syntax less-than-obvious, but then you'd be stuck with
            the explicit call to Substring() before Parse().

            How many other ways can we skin this cat? :)

            Pete

            Comment

            • Paul E Collins

              #7
              Re: Get number from end of name

              "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote:
              How many other ways can we skin this cat? :)
              static int GetNumberAtEnd( string s)
              {
              int val = 0, pos = s.Length - 1;
              while (pos 0 && s[pos] >= '0' && s[pos] <= '9')
              {
              val += (s[pos] - '0') * (int) Math.Pow(10, s.Length - pos - 1);
              pos--;
              }
              return val;
              }

              Eq.


              Comment

              • Jon Skeet [C# MVP]

                #8
                Re: Get number from end of name

                Peter Duniho <NpOeStPeAdM@nn owslpianmk.comw rote:

                <snip>
                How many other ways can we skin this cat? :)
                Create a parameterised SQL query and get the query engine to do the
                work? Or we could always set up a web service for it, and maybe write a
                custom LINQ provider to call that web service.

                --
                Jon Skeet - <skeet@pobox.co m>
                Web site: http://www.pobox.com/~skeet
                Blog: http://www.msmvps.com/jon.skeet
                C# in Depth: http://csharpindepth.com

                Comment

                • Paul E Collins

                  #9
                  Re: Get number from end of name

                  "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote:
                  Use Character.IsDig it
                  But are digits recognised by Char.IsDigit guaranteed to parse as integers?
                  Even on a Western system, Hebrew numerals would count as digits (in the
                  character sense), wouldn't they?

                  Eq.


                  Comment

                  • Jon Skeet [C# MVP]

                    #10
                    Re: Get number from end of name

                    Paul E Collins <find_my_real_a ddress@CL4.orgw rote:
                    "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote:
                    >
                    Use Character.IsDig it
                    >
                    But are digits recognised by Char.IsDigit guaranteed to parse as integers?
                    Even on a Western system, Hebrew numerals would count as digits (in the
                    character sense), wouldn't they?
                    Hmm... not sure. It's only *decimal* digits, but I don't know what
                    other characters are in DecimalDigitNum ber.

                    --
                    Jon Skeet - <skeet@pobox.co m>
                    Web site: http://www.pobox.com/~skeet
                    Blog: http://www.msmvps.com/jon.skeet
                    C# in Depth: http://csharpindepth.com

                    Comment

                    • Paul E Collins

                      #11
                      Re: Get number from end of name

                      "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote:
                      But are digits recognised by Char.IsDigit guaranteed to parse as
                      integers? Even on a Western system, Hebrew numerals would count as
                      digits (in the character sense), wouldn't they?
                      >
                      Hmm... not sure. It's only *decimal* digits, but I don't know what other
                      characters are in DecimalDigitNum ber.
                      char ch = (char) 0x667; // Arabic-Indic Digit Seven
                      Console.WriteLi ne(Char.IsDigit (ch)); // "True"
                      int i = Int32.Parse(ch. ToString()); // throws FormatException

                      I suppose Int32.Parse *might* work differently depending on your system
                      locale, but in either case Char.IsDigit will check whether the character is
                      a digit in *any* locale, so it's not safe to use for this purpose.

                      Eq.


                      Comment

                      • Jon Skeet [C# MVP]

                        #12
                        Re: Get number from end of name

                        Paul E Collins <find_my_real_a ddress@CL4.orgw rote:
                        "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote:
                        >
                        But are digits recognised by Char.IsDigit guaranteed to parse as
                        integers? Even on a Western system, Hebrew numerals would count as
                        digits (in the character sense), wouldn't they?
                        Hmm... not sure. It's only *decimal* digits, but I don't know what other
                        characters are in DecimalDigitNum ber.
                        >
                        char ch = (char) 0x667; // Arabic-Indic Digit Seven
                        Console.WriteLi ne(Char.IsDigit (ch)); // "True"
                        int i = Int32.Parse(ch. ToString()); // throws FormatException
                        >
                        I suppose Int32.Parse *might* work differently depending on your system
                        locale, but in either case Char.IsDigit will check whether the character is
                        a digit in *any* locale, so it's not safe to use for this purpose.
                        Yup. It's a shame there isn't a property for this, as it's reasonably
                        common.

                        --
                        Jon Skeet - <skeet@pobox.co m>
                        Web site: http://www.pobox.com/~skeet
                        Blog: http://www.msmvps.com/jon.skeet
                        C# in Depth: http://csharpindepth.com

                        Comment

                        • Ben Voigt [C++ MVP]

                          #13
                          Re: Get number from end of name

                          Jon Skeet [C# MVP] wrote:
                          Paul E Collins <find_my_real_a ddress@CL4.orgw rote:
                          >"Jon Skeet [C# MVP]" <skeet@pobox.co mwrote:
                          >>
                          >>>But are digits recognised by Char.IsDigit guaranteed to parse as
                          >>>integers? Even on a Western system, Hebrew numerals would count as
                          >>>digits (in the character sense), wouldn't they?
                          >>>
                          >>Hmm... not sure. It's only *decimal* digits, but I don't know what
                          >>other characters are in DecimalDigitNum ber.
                          >>
                          >char ch = (char) 0x667; // Arabic-Indic Digit Seven
                          >Console.WriteL ine(Char.IsDigi t(ch)); // "True"
                          >int i = Int32.Parse(ch. ToString()); // throws FormatException
                          >>
                          >I suppose Int32.Parse *might* work differently depending on your
                          >system locale, but in either case Char.IsDigit will check whether
                          >the character is a digit in *any* locale, so it's not safe to use
                          >for this purpose.
                          >
                          Yup. It's a shame there isn't a property for this, as it's reasonably
                          common.
                          Cue requests for extension properties.


                          Comment

                          Working...