Convert an signed int to 8 digit hex in flex - actionscript-3

How can i convert a type int into 8 digit hex decimal in flex
I need a function similiar in c# [ ToString("X8") ]. This function does the job in c#.
But what is the option in flex ?

As described in the docs, it's pretty much the same:
var myInt:int = 255;
var hex:String = myInt.toString(16);
trace(hex); //outputs "ff"
See http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/int.html#toString()
If it's colors you're after: the docs describe how to handle that case too.
There is however no built-in way to add the leading zeros. You can use a method like this one to do that:
public function pad(s:String, pattern:String="0", minChars:int=8):String {
while (s.length < minChars) s = pattern + s;
return s;
}
trace(pad(hex)); //000000ff

Note: this is for 6 digit hex colors but could easily be modified to any number of hex digits.
Found a lot of ways of outputting padded hex values that relied heavily on string padding.
I wasn't really happy with any of those so this is what I came up with: (as a bonus it fits on one line) You could even shorten it by removing the toUpperCase() call as case is really irrelevant.
"0x"+ (i+0x1000000).toString(16).substr(1,6).toUpperCase()
If you want to floor or ceiling that to black and white and put that in a function:
public static function toHexColor(i:Number):String {
return i<0 ? "0x000000" : i>0xFFFFFF ? "0xFFFFFF" : "0x"+ (i+0x1000000).toString(16).substr(1,6).toUpperCase() ;
}
Here is a more expanded version with comments:
public static function toHexColor(i:Number):String {
//enforce ceiling and floor
if(i>0xFFFFFF){ return "0xFFFFFF";}
if(i<0){return "0x000000";}
//add the "magic" number
i += 0x1000000;
//append the 0x and strip the extra 1
return "0x"+ i.toString(16).substr(1,6).toUpperCase();
}

Related

Flex: Replacing characters in a string based on a mask

I am attempting to apply a mask to another string to replace all wildcards in one string with the matching characters in the matching index while keeping the non-wildcard characters.
Eg:
starting string: "1234-234-3456-45-9876"
mask string: "____-___-0001-__-____"
when applied together: "1234-234-0001-45-9876"
Is this some usage of Regex I haven't seen before? I tried to understand the string.replace() type methods, but I don't think these apply.
Hope this will help you:
private function checkString():void
{
var starting:String = "1234-234-3456-45-9876";
var mask:String = "____-___-0001-__-____";
for(var i:int=0;i<starting.length;i++)
{
if(mask.charAt(i).match("[0-9]"))
{
starting = starting.substr(0,i) + mask.charAt(i) + starting.substr(i+1);
}
}
Alert.show(starting);
}
It will mask your string. Check result of alert.

Last Character Of A Variable Name

I'm trying to find last character of a variable. My code is:
trace(this[String.fromCharCode(num) + i]);
I also need second character by backwards. Sorry for my English.
Edit:
I think I couldn't explain it exactly. I have some variables. One of them is: this["h5"]
I want it to return 5.
Is this what you're trying to do?
function lastNameChar(target:DisplayObject):String
{
return target.name.substr(target.name.length - 1, 1);
}
trace(lastNameChar(this["h5"])); // 5
You should be able to make use of a string's length and get characters of it using charAt.
So, if you had the following:
var myString : String = "abcdefg";
You could do this to get the last character:
myString.charAt(myString.length - 1); // (since the first character is at index 0
and to get the next to last character:
myString.charAt(myString.length - 2);
function getLastCharInString($s:String):String
{
return $s.substr($s.length-1,$s.length);
}
function getSecondLastCharInString($s:String):String
{
return $s.substr($s.length-2,$s.length);
}

formatting numbers in different culture

I have below XAML
<TextBlock HorizontalAlignment="{Binding AyaHorizentalAlignment}" Padding="20,0,30,0" Text="{Binding Aya}" Foreground="Black" FontSize="50" TextWrapping="Wrap" />
and Code behind
System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("fa-IR");
for (int rowIndex = startingAya; rowIndex < totalAyas; rowIndex++)
{
quranTextByLine = Regex.Replace(reader.ReadLine(), #"[|\d|]", string.Empty) + "﴿" + string.Format(culture,"{0}",counter++) + "﴾";
quranTranslationByLine = Regex.Replace(translationReader.ReadLine(), #"[|\d|]", string.Empty);
_sura.Add(new Sura() { Aya = quranTextByLine, AyaTranslation = quranTranslationByLine });
}
I want to show "counter" in farsi / arabic format and the format is "۱۲۳۴۵۶۷۸۹", I don't know how to format "counter"? (I have also the fonts available)
Thanks,
The 'full' .NET Framework contains the property NumberFormatInfo.DigitSubstitution. If you were developing in .NET, this would be the property you would use if you wanted numbers to be formatted using Arabic-Indic digits. However, this property isn't available in the Windows Phone version of the framework.
If a property or method exists in the full .NET Framework but not in Windows Phone, this is normally an indication that the functionality isn't in the Windows Phone version of the framework. As a result you will have to do the conversion of numbers to strings using Arabic-Indic digits yourself.
It's possible to write a conversion method that converts a number to a string using Latin digits, and then replaces the Latin digits with Arabic-Indic digits, for example:
private const char LatinDigitZero = '0';
private const char ArabicIndicDigitZero = '\u0660';
public static string ConvertToArabicIndicString(int number)
{
string result = string.Format("{0:d}", number);
for (int digit = 0; digit <= 9; ++digit)
{
result = result.Replace((char)(LatinDigitZero + digit), (char)(ArabicIndicDigitZero + digit));
}
return result;
}
This could easily be adapted to take a CultureInfo object as an additional parameter.
This uses the fact that the Arabic-Indic digits corresponding to the Latin digits 0 to 9 are Unicode characters \u0660 to \u0669, respectively.
I gave this a quick test and as far as I could tell it worked. However, I'm not at all fluent in any language that uses Arabic-Indic digits so I can't say whether this method converts the number to a string correctly. In particular, I don't know whether this method generates a number with the digits in the right order or handles negative numbers correctly. Hopefully, any necessary such modifications should be easy for you to make.

ActionScript3 - add thousands separator to negative values

This question relates to an animated map template which we have developed at the UKs Office for National Statistics. It has been applied to many datasets and geographies many uses without problem. For example,
http://www.ons.gov.uk/ons/interactive/vp3-census-map/index.html
http://www.statistica.md/pageview.php?l=ro&idc=390&id=3807
The .fla calls on a supporting .as file (see below) to introduce a thousand separator (in the UK a comma, in Germany a full stop (period) defined elsewhwere.
However, the dataset I am currently mapping has large negative values, and it tutrns out that the ORIGINAL HELPER FUNCTION below does not like negative values with 3, 6, 9 or 12 (etc) digits.
-100 to -999 for instance are rendered NaN,100 to NaN,999.
This is because such values are recognised as being 4 digits long. They are being split, the comma introduced, and the -ve sign is misunderstood.
I reckon the approach must be to use absolute values, add in the comma and then (for the negative values) add the -ve sign back in afterwards. But so far, trials of the ADAPTED HELPER FUNCTION have produced only error. :-(
Can anyone tell me how to put the -ve sign back in , please?
Many thanks.
Bruce Mitchell
==================================================================================
//ORIGINAL HELPER FUNCTION: ACCEPTS A NUMBER AND RETURNS A STRING WITH THOUSANDS SEPARATOR ATTACHED IF NECESSARY
function addThouSep(num) {
/*
a. Acquire the number - 'myTrendValue' or 'myDataValue' - from function calcValues
b. Record it (still as a number) to data precision.
1. Turn dataORtrend into a string
2. See if there is a decimal in it.
3. If there isn't, just run the normal addThouSep.
4. If there is, run addThouSep just on the first bit of the string - then add the decimal back on again at the end.
*/
var myNum:Number = correctFPE(num); // Create number variable myNum and populate it with 'num'
// (myTrendvalue or myData Value from calcValues function) passed thru 'correctPFE'
var strNum:String = myNum+""; // Create string version of the dataORtrend number - so instead of 63, you get '63'
var myArray = strNum.split("."); // Create array representing elements of strNum, split by decimal point.
//trace(myArray.length); // How long is the array?
if (myArray.length==1) { // Integer, no decimal.
if (strNum.length < 4)//999 doesn't need a comma.
return strNum;
return addThouSep(strNum.slice(0, -3))+xmlData.thouSep+strNum.slice(-3);
}
else { // Float, with decimal
if (myArray[0].length < 4)//999 doesn't need a comma
return strNum;
return (addThouSep(myArray[0].slice(0, -3))+xmlData.thouSep+myArray[0].slice(-3)+"."+myArray[1]);
}
}
==================================================================================
//ADAPTED HELPER FUNCTION: ACCEPTS A NUMBER AND RETURNS A STRING WITH THOUSANDS SEPARATOR ATTACHED IF NECESSARY
function addThouSep(num) {
/*
a. Acquire the number - 'myTrendValue' or 'myDataValue' - from function calcValues
b. Record it (still as a number) to data precision.
1. Turn dataORtrend into a string
2. See if there is a decimal in it.
3. If there isn't, just run the normal addThouSep.
4. If there is, run addThouSep just on the first bit of the string - then add the decimal back on again at the end.
*/
var myNum:Number = correctFPE(num); // Create number variable myNum and populate it with 'num'
// (myTrendvalue or myData Value from calcValues function) passed thru 'correctPFE'
var myAbsNum:Number = Math.abs(myNum); // ABSOLUTE value of myNum
var strNum:String = myAbsNum+""; // Create string version of the dataORtrend number - so instead of 63, you get '63'
var myArray = strNum.split("."); // Create array representing elements of strNum, split by decimal point.
//trace(myArray.length); // How long is the array?
if (myNum <0){ // negatives
if (myArray.length==1) { // Integer, no decimal.
if (strNum.length < 4)//999 doesn't need a comma.
return strNum;
return addThouSep(strNum.slice(0, -3))+xmlData.thouSep+strNum.slice(-3);
}
else { // Float, with decimal
if (myArray[0].length < 4)//999 doesn't need a comma
return strNum;
return (addThouSep(myArray[0].slice(0, -3))+xmlData.thouSep+myArray[0].slice(-3)+"."+myArray[1]);
}
}
else // positive
if (myArray.length==1) { // Integer, no decimal.
if (strNum.length < 4)//999 doesn't need a comma.
return strNum;
return addThouSep(strNum.slice(0, -3))+xmlData.thouSep+strNum.slice(-3);
}
else { // Float, with decimal
if (myArray[0].length < 4)//999 doesn't need a comma
return strNum;
return (addThouSep(myArray[0].slice(0, -3))+xmlData.thouSep+myArray[0].slice(-3)+"."+myArray[1]);
}
}
==================================================================================
If you're adding commas often (or need to support numbers with decimals) then you may want a highly optimized utility function and go with straightforward string manipulation:
public static function commaify( input:Number ):String
{
var split:Array = input.toString().split( '.' ),
front:String = split[0],
back:String = ( split.length > 1 ) ? "." + split[1] : null,
pos:int = input < 0 ? 2 : 1,
commas:int = Math.floor( (front.length - pos) / 3 ),
i:int = 1;
for ( ; i <= commas; i++ )
{
pos = front.length - (3 * i + i - 1);
front = front.slice( 0, pos ) + "," + front.slice( pos );
}
if ( back )
return front + back;
else
return front;
}
While less elegant it's stable and performant — you can find a comparison suite at my answer of a similar question https://stackoverflow.com/a/13410560/934195
Why not use something simple like this function I've made?
function numberFormat(input:Number):String
{
var base:String = input.toString();
base = base.split("").reverse().join("");
base = base.replace(/\d{3}(?=\d)/g, "$&,");
return base.split("").reverse().join("");
}
Tests:
trace( numberFormat(-100) ); // -100
trace( numberFormat(5000) ); // 5,000
trace( numberFormat(-85600) ); // -85,600
Explanation:
Convert the input number to a string.
Reverse it.
Use .replace() to find all occurrences of three numbers followed by another number. We use $&, as the replacement, which basically means take all of those occurences and replace it with the value we found, plus a comma.
Reverse the string again and return it.
Did you try using the built in Number formatting options that support localized number values:
Localized Formatting with NumberFormatter

Randomly selecting an object property

I guess a step back is in order. My original question is at the bottom of this post for reference.
I am writing a word guessing game and wanted a way to:
1. Given a word length of 2 - 10 characters, randomly generate a valid english word to guess
2.given a 2 - 10 character guess, ensure that it is a valid english word.
I created a vector of 9 objects, one for each word length and dynamically created 172000
property/ value pairs using the words from a word list to name the properties and setting their value to true. The inner loop is:
for (i = 0; i < _WordCount[wordLength] - 2; i)
{
_WordsList[wordLength]["" + _WordsVector[wordLength][i++]] = true;
}
To validate a word , the following lookup returns true if valid:
function Validate(key:String):Boolean
{
return _WordsList[key.length - 2][key]
}
I transferred them from a vector to objects to take advantage of the hash take lookup of the properties. Haven't looked at how much memory this all takes but it's been a useful learning exercise.
I just wasn't sure how best to randomly choose a property from one of the objects. I was thinking of validating whatever method I chose by generating 1000 000 words and analyzing the statistics of the distribution.
So I suppose my question should really first be am I better off using some other approach such as keeping the lists in vectors and doing a search each time ?
Original question
Newbie first question:
I read a thread that said that traversal order in a for.. in is determined by a hash table and appears random.
I'm looking for a good way to randomly select a property in an object. Would the first element in a for .. in traversing the properties, or perhaps the random nth element in the iteration be truly random. I'd like to ensure that there is approximately an equal probability of accessing a given property. The Objects have between approximately 100 and 20000 properties. Other approaches ?
thanks.
Looking at the scenario you described in your edited question, I'd suggest using a Vector.<String> and your map object.
You can store all your keys in the vector and map them in the object, then you can select a random numeric key in the vector and use the result as a key in the map object.
To make it clear, take a look at this simple example:
var keys:Vector.<String> = new Vector.<String>();
var map:Object = { };
function add(key:String, value:*):void
{
keys.push(key);
map[key] = value;
}
function getRandom():*
{
var randomKey = keys[int(Math.random() * keys.length)];
return map[randomKey];
}
And you can use it like this:
add("a", "x");
add("b", "y");
add("c", "z");
var radomValue:* = getRandom();
Using Object instead of String
Instead of storing the strings you can store objects that have the string inside of them,
something like:
public class Word
{
public var value:String;
public var length:int;
public function Word(value:String)
{
this.value = value;
this.length = value.length;
}
}
Use this object as value instead of the string, but you need to change your map object to be a Dictionary:
var map:Dictionary = new Dictionary();
function add(key:Word, value:*):void
{
keys.push(key);
map[key] = value;
}
This way you won't duplicate every word (but will have a little class overhead).