WoWInterface

WoWInterface (http://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (http://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Dividing hundreds and thousands by a comma (http://www.wowinterface.com/forums/showthread.php?t=45471)

Aanson 12-18-12 11:32 AM

Dividing hundreds and thousands by a comma
 
Hi again all!

This isn't really too essential, and I'm maybe just being a bit too picky here, but is there any way to do the following:

Convert 123123 to 123,123 ?

I created the following function for use on the AUCTION_HOUSE_CLOSED event:

Lua Code:
  1. M.GetData_CalculateListingValue = function()
  2.     local announce = C.GetActiveProfile().Modules[module].sayListingValueOnClose;
  3.     if (not announce) then return nil; end
  4.     local value = 0;
  5.     local pageAuctions, totalAuctions = GetNumAuctionItems("owner");
  6.     for i = 1, totalAuctions do
  7.         value = ( value + select(10, GetAuctionItemInfo("owner", i)) );
  8.     end
  9.     if (value > 0) then
  10.         return GetCoinTextureString(value);
  11.     end
  12.     return nil;
  13. end

I've discovered though that GetCoinTextureString() returns the number format described above. I've tried my hand at using string.format but I've not had any luck so far.


One other completely unrelated question while I'm here. When a variable is expressed within a function (for example "announce" in the function above; I understand it to be local to that function only. What I'm not sure of though is, what if I omitted the 'local'? Would it become a Global and pollute the global namespace, or will it still be local only to that function?

Also, what about this example?:

Lua Code:
  1. M.GetData_CalculateListingValue = function(announce)
  2. local announce = (announce or false);
  3. -- doing stuff with announce
  4. end

Am I still required to prefix 'announce' with 'local' or should I not be doing that?

Thanks in advance for any help you guys could give with this.

Seerah 12-18-12 01:40 PM

If you take away the "local", then yes - it will be a global. Unless you declare that variable as local in your upvalues (outside of the function, therefore local to your whole Lua file.)

Torhal 12-18-12 02:05 PM

Blizzard's build-in UI function BreakUpLargeNumbers() does what you need.

SDPhantom 12-18-12 02:42 PM

Unfortunately, BreakUpLargeNumbers() only works on number values, not strings such as one returned by GetCoinTextureString(). The following code will try to reformat an already formatted string. Note, don't try to use this on strings that contain numbers with a decimal component.

Lua Code:
  1. function ReformatNumberString(str)
  2.     local repstr="%1"..LARGE_NUMBER_SEPERATOR.."%2";
  3.  
  4. --  Initial replacement of a number group at the end of the string
  5.     str=str:gsub("(%d)(%d%d%d)$",repstr));
  6.  
  7. --  Note repeat checks post-loop, unlike while that checks pre-loop
  8. --  This not only guarantees the loop code to run at least once before the condition is checked, but allows use of locals inside the loop for the condition
  9.     repeat
  10. --      Writing to an upvalue actually uses one additional opcode from just reregistering a local inside a loop
  11.         local numrep;
  12.  
  13. --      Looping replacement of a number group followed by a non-number
  14.         str,numrep=str:gsub("(%d)(%d%d%d%D)",repstr));
  15.     until numrep<=0
  16. end

Aanson 12-18-12 05:12 PM

Quote:

Originally Posted by Seerah (Post 270841)
If you take away the "local", then yes - it will be a global. Unless you declare that variable as local in your upvalues (outside of the function, therefore local to your whole Lua file.)

Thanks all.

So with this example, just so I've got it straight in my head:

Lua Code:
  1. M.GetData_CalculateListingValue = function(announce)
  2.     announce = (announce or false);
  3.     -- doing stuff with announce
  4. end

The function argument 'announce' will now be a global because it wasn't declared local within the function?

Torhal 12-18-12 05:17 PM

No. In your example, "announce" is a parameter which is passed in from elsewhere, so it is either already global or local to the scope from whence it originated. Also, the line:

Code:

announce = (announce or false)
...is usually semantically identical to saying "This boolean value is either what it already equates to or false" unless you really need to differentiate between "false" and "nil".

SDPhantom 12-19-12 05:28 AM

To further clarify, function arguments are treated as local variables and only exist within the scope of the function itself.

Farmbuyer 12-19-12 03:24 PM

Quote:

Originally Posted by Aanson (Post 270838)
Convert 123123 to 123,123 ?

This has been floating around a long time, I can't take credit for it. Optimizations and input checking is left as an exercise for the future googler.

Code:

function comma (str)
    str = tostring(str)  // now you can feed it numbers instead of strings
    local prefix, number, suffix = str:match"(%D*%d)(%d+)(%D*)"
    return prefix .. number:reverse():gsub("(%d%d%d)","%1,"):reverse() .. suffix
end

print(comma("300"))
print(comma("300g"))
print(comma("-1234g"))
print(comma("$42424242US"))


Clamsoda 12-19-12 04:01 PM

I found this function while browsing the WoWAce forums. I believe the credit goes to Phanx, but I don't think the post explicitly stated that she wrote it.

Lua Code:
  1. local function numformat(num)
  2.     if not num then return 0 end
  3.     if abs(num) < 1000 then return num end
  4.     local neg = num < 0 and "-" or ""
  5.     local left, mid, right = tostring(abs(num)):match("^([^%d]*%d)(%d*)(.-)$")
  6.     return ("%s%s%s%s"):format(neg, left, mid:reverse():gsub("(%d%d%d)", "%1,"):reverse(), right)
  7. end

Only works for whole numbers apparently.

SDPhantom 12-19-12 09:16 PM

Scroll up to my post above, should be #4. Unlike the code posted in the last couple posts, the one I wrote should work specifically on GetCoinTextureString(). This is because the pattern matching works on ALL numbers in the string, not just a random one of the group.

SDPhantom 12-19-12 09:59 PM

I came up with a little more complex code. This should handle decimal numbers and still support reformatting multiple numbers in a string. It works by nesting string:gsub() calls in replacement functions. The base function seeks out all numbers and calls SplitDecimal() to modify them. SplitDecimal()'s entire purpose is for decimal number support and will only grab the integer section of a decimal number, calling AddCommas() on it and leaving the rest alone. AddCommas() is what inserts the locale-dependent separator as stored in LARGE_NUMBER_SEPERATOR. This global is what's used in the Default UI code for BreakUpLargeNumbers().
Lua Code:
  1. local ReformatNumberString; do
  2.     local AddCommas(pre,post) return pre..post:reverse():gsub("(%d%d%d)","%1"..LARGE_NUMBER_SEPERATOR):reverse(); end
  3.     local SplitDecimal(str) return str:gsub("^(%d)(%d+)",AddCommas); end
  4.     function ReformatNumberString(str) return str:gsub("[%d%.]+",SplitDecimal); end
  5. end

Aanson 12-20-12 06:09 AM

Quote:

Originally Posted by SDPhantom (Post 270917)
I came up with a little more complex code. This should handle decimal numbers and still support reformatting multiple numbers in a string. It works by nesting string:gsub() calls in replacement functions. The base function seeks out all numbers and calls SplitDecimal() to modify them. SplitDecimal()'s entire purpose is for decimal number support and will only grab the integer section of a decimal number, calling AddCommas() on it and leaving the rest alone. AddCommas() is what inserts the locale-dependent separator as stored in LARGE_NUMBER_SEPERATOR. This global is what's used in the Default UI code for BreakUpLargeNumbers().
Lua Code:
  1. local ReformatNumberString; do
  2.     local AddCommas(pre,post) return pre..post:reverse():gsub("(%d%d%d)","%1"..LARGE_NUMBER_SEPERATOR):reverse(); end
  3.     local SplitDecimal(str) return str:gsub("^(%d)(%d+)",AddCommas); end
  4.     function ReformatNumberString(str) return str:gsub("[%d%.]+",SplitDecimal); end
  5. end

Thanks very much everyone for going out of your way to help.

Special thanks to Phantom... i'll give that code a wee try today :)

Aanson


All times are GMT -6. The time now is 10:34 AM.

vBulletin © 2014, Jelsoft Enterprises Ltd
©2012 ZAM Network LLC