I need to format numbers with commas as thousand seperators, for example:
1234 = 1,234
1234.50 = 1,234.50
12345.60 = 12,345.60
123456.70 = 123,456.70
1234567.80 = 1,234,567.80
etc etc
This needs to work for numbers with decimal values or without
i.e. both 1234567.80 and 1234567
This is for Actionscript 2 in a Coldfusion / Flash application, so normal actionscript is being used. I have seen a couple of solutions on the net but none quite do the trick.
So far I have the function below, but it is not formatting correctly when decimals are provided.For example: 21898.5 becomes 2,188,8.5.
Please could you help me find the bug or offer an alternative solution that fulfils the requriements.
Thanks
_global.NumberFormat = function(theNumber)
{
var myArray:Array;
var numberPart:String;
var decPart:String;
var result:String = '';
var numString:String = theNumber.toString();
if(theNumber.indexOf('.') > 0)
{
myArray = theNumber.split('.');
numberPart = myArray[0];
decPart = myArray[1];
}
else
{
numberPart = numString;
}
while (numString.length > 3)
{
var chunk:String = numString.substr(-3);
numString = numString.substr(0, numString.length - 3);
result = ',' + chunk + result;
}
if (numString.length > 0)
{
result = numString + result;
}
if(theNumber.indexOf('.') > 0)
{
result = result + '.' + decPart;
}
//alert('Result: ' + result);
return result;
}
You could try this:
_global.NumberFormat = function(numString)
{
numString = String(numString);
var index:Number = numString.indexOf('.');
var decimal:String;
if(index > 0) {
var splitByDecimal:Array = numString.split(".");
//return NumberFormat(splitByDecimal[0])+"."+splitByDecimal[1];
numString = splitByDecimal[0];
decimal = splitByDecimal[1];
} else if(index === 0) {
return "0"+numString;
}
var result:String = '';
while (numString.length > 3 ) {
var chunk:String = numString.substr(-3);
numString = numString.substr(0, numString.length - 3);
result = ',' + chunk + result;
}
result = numString + result;
if(decimal) result = result + "." + decimal;
return result;
}
It splits the number by the decimal if present(compensating for an illegal '.01234' if required), and uses recursion so call itself on the split element.
For your example numbers this traces:
1,234
1,234.50
12,345.60
123,456.70
1,234,567.80
Just for fun
This is why your original code didn't work:
After creating a string representation of the number (var numString:String = theNumber.toString();) you then carried on using the actual number rather than the string version.
After assigning a value to number part you then continued to perform operations on numString rather than numberPart.
A corrected version looks like this:
_global.NumberFormat = function(theNumber)
{
var myArray:Array;
var numberPart:String;
var decPart:String;
var result:String = '';
var numString:String = theNumber.toString();
if(numString.indexOf('.') > 0)
{
myArray = numString.split('.');
numberPart = myArray[0];
decPart = myArray[1];
}
else
{
numberPart = numString;
}
while (numberPart.length > 3)
{
var chunk:String = numberPart.substr(-3);
numberPart = numberPart.substr(0, numberPart.length - 3);
result = ',' + chunk + result;
}
if (numberPart.length > 0)
{
result = numberPart + result;
}
if(numString.indexOf('.') > 0)
{
result = result + '.' + decPart;
}
//alert('Result: ' + result);
return result;
}
public static function formatNumberString(value:Number,separator:String):String {
var result:String = "";
var digitsCount:Number = value.toString().length;
separator = separator || ",";
for (var i:Number = 0; i < digitsCount; i++) {
if ((digitsCount - i) % 3 == 0 && i != 0) {
result += separator;
}
result += value.toString().charAt(i);
}
return result;
}
Try this out, works fine for me:
var largeNumber:String=new String(1000000.999777);
var fAr:Array=largeNumber.split(".");
var reg:RegExp=/\d{1,3}(?=(\d{3})+(?!\d))/;
while(reg.test(fAr[0]))
fAr[0]=fAr[0].replace(reg,"$&,");
var res:String=fAr.join(".");
trace(res);
Trace: 1,000,000.999777
Related
I'm new to Dart. I was trying to convert integer to roman. But It returns nothing. Can you guys help me? here is my code sample.
this code is from the Leetcode problem section.
class Solution {
String intToRoman(int num) {
List<int> numbers = [1,4,5,9,10,40,50,90,100,400,500,900,1000];
List<String> romans = ["I","IV","V","IX","X","XL","L","XC","C","CD","D","CM", "M"];
int index = romans.length - 1;
String roman = '';
for(num >0;numbers[index]<=num;){
roman += romans[index];
num -= numbers[index];
index -= 1;
}
return roman;
}
}
just change a little bit on the logic
.try on dartpad: https://dartpad.dev/?id
void main() {
print (intToRoman(30)); // result: XXX
}
String intToRoman(int num) {
List<int> numbers = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
List<String> romans = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"];
String roman = '';
for (int i = 0; i < numbers.length; i++) {
while (num >= numbers[i]) {
roman += romans[i];
num -= numbers[i];
}
}
return roman;
}
This solution is based on Wiki:
class Solution {
/// digit: 3=Thousands(10³), 2=Hundreds(10²), 1=Tens(10), 0=Units(1)
/// Range for roman numerals: 1...3999
static final romanNumerals = <int,Map<int,String>>{
1 : {3:'M', 2:'C', 1:'X', 0:'I'},
2 : {3:'MM', 2:'CC', 1:'XX', 0:'II'},
3 : {3:'MMM', 2:'CCC', 1:'XXX', 0:'III'},
4 : {2:'CD', 1:'XL', 0:'IV'},
5 : {2:'D', 1:'L', 0:'V'},
6 : {2:'DC', 1:'LX', 0:'VI'},
7 : {2:'DCC', 1:'LXX', 0:'VII'},
8 : {2:'DCCC', 1:'LXXX', 0:'VIII'},
9 : {2:'CM', 1:'XC', 0:'IX'},
};
/* ---------------------------------------------------------------------------- */
Solution();
/* ---------------------------------------------------------------------------- */
String intToRoman(int number) {
if (number < 1 || number >= 4000) return '';
var list = number.toString().split('').map(int.parse).toList();
var buffer = StringBuffer();
final len = list.length;
for (var i = 0; i < len; i++) {
var digit = list[i];
if (digit == 0) continue;
buffer.write(romanNumerals[digit]![len - 1 - i]);
}
return buffer.toString();
}
/* ---------------------------------------------------------------------------- */
void intToRoman2(int number) {
print(intToRoman(number));
}
}
void main(List<String> args) {
Solution()
..intToRoman2(3)
..intToRoman2(58)
..intToRoman2(1994)
;
}
Output:
III
LVIII
MCMXCIV
This code was already sent to LeetCode with the following results:
Runtime: 1130 ms, faster than 27.96% of Dart online submissions for Integer to Roman.
Memory Usage: 150.5 MB, less than 44.09% of Dart online submissions for Integer to Roman.
why not use the simple way?
I use this extension to convert english numbers to persian numbers
extension StringExtensions on String {
String persianNumber() {
String number = this;
number = number.replaceAll("1", "۱");
number = number.replaceAll("2", "۲");
number = number.replaceAll("3", "۳");
number = number.replaceAll("4", "۴");
number = number.replaceAll("5", "۵");
number = number.replaceAll("6", "۶");
number = number.replaceAll("7", "۷");
number = number.replaceAll("8", "۸");
number = number.replaceAll("9", "۹");
number = number.replaceAll("0", "۰");
return number;
}
}
extension IntExtensions on int {
String persianNumber() {
String number = this.toString();
number = number.replaceAll("1", "۱");
number = number.replaceAll("2", "۲");
number = number.replaceAll("3", "۳");
number = number.replaceAll("4", "۴");
number = number.replaceAll("5", "۵");
number = number.replaceAll("6", "۶");
number = number.replaceAll("7", "۷");
number = number.replaceAll("8", "۸");
number = number.replaceAll("9", "۹");
number = number.replaceAll("0", "۰");
return number;
}
}
Is there anyway to round up a double value?
I want result always rounded up.
int offSet = (totalRecords / 10).round();
It's ceil:
Returns the least integer no smaller than this.
int offSet = (totalRecords / 10).ceil();
Here I'm rounding it to the next double or to next 0.5;
Sample: If its 6.6 then rount to 7.0. If its 6.2, then round to 6.5. See code bellow:
String arredonde(String n) {
final List x = n.split('.'); //break in to a list
if (x.length > 1) { //if its 0, then its already a rounded number or integer
int fstNmbr = int.parse(x[0]);
final int lstNmbrs = int.parse(x[1]);
if (lstNmbrs > 5) {
fstNmbr = fstNmbr + 1;
final String finalNumber = fstNmbr.toStringAsFixed(1);
return finalNumber;
} else {
if (lstNmbrs != 0) {
final double finalNumber = fstNmbr + 0.5;
return finalNumber.toStringAsFixed(1);
} else {
return n;
}
}
} else {
return n;
}
}
try with
num.parse((totalRecords / 10).toStringAsFixed(3))
if you want 3 decimal
Now you have something like you want. I choose sup to 5 to round up, you can change if you want
num offSet = (totalRecords / 10);
var eval = offSet.toStringAsFixed(1).split('.');
var res =
int.parse(eval[1]) > 5 ? int.parse(eval[0]) + 1 : int.parse(eval[0]);
print(res);
Setting colors of cells 1 by 1 is extremely slow. It is advised to do that by assigning an array to the range. I read about that and there is often refered to the following sample. However I can't get this to work so it doesn't help me.
var cell = sheet.getRange('a1');
var colors = new Array(100);
for (var y = 0; y < 100; y++) {
xcoord = xmin;
colors[y] = new Array(100);
for (var x = 0; x < 100; x++) {
colors[y][x] = getColorFromCoordinates(xcoord, ycoord);
xcoord += xincrement;
}
ycoord -= yincrement;
}
sheet.getRange(1, 1, 100, 100).setBackgroundColors(colors);
My piece of code is the following and ends with the message (error): Cannot convert array to object[[]], pointing at the last line.
function TabelMarkeren() {
var selection = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef") // 6 by 3;
var colors = [];
for (var row = 1; row <= selection.getNumRows(); ++row) {
var cell = selection.getCell(row, 1);
if (cell.isBlank()) {
colors[row, 1] = "#86d8b6";
}// if
else {
colors[row, 1] = "c4c4a4";
}// else
colors[row, 2] = "blue";
colors[row, 3] = "green";
}// for
SpreadsheetApp.getActiveSpreadsheet().
getRangeByName("Proef").setBackgrounds(colors);
}
When I use a Browser.msgBox . . to show me some values from the array. It is ok. But clearly setBackgroundColors wants an object and not an array.
The setBackgrounds expect the value in [][] and you are passing the values in []. Refer the below code.
function TabelMarkeren() {
var selection = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef") // 6 by 3;
var finalColors = [];
for (var row = 1; row <= selection.getNumRows(); ++row) {
var colors = [];
var cell = selection.getCell(row, 1);
if (cell.isBlank()) {
colors[row, 1] = "#86d8b6";
} // if
else {
colors[row, 1] = "c4c4a4";
} // else
colors[row, 2] = "blue";
colors[row, 3] = "green";
finalColors.push(colors)
} // for
Logger.log(colors)
SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef").setBackgrounds(finalColors);
}
Thank you Ritz, I have it working now.
I also had to change the colomn indexes from 1,2,3 to 0,1,2. That was another mistake. The code is now:
function TabelMarkerenn() {
var selection = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Proef");
var finalColors = []
for (var row = 1; row <= selection.getNumRows(); ++row) {
var colors = [];
var cell = selection.getCell(row, 1);
if (cell.isBlank()) {
colors[row, 0] = "#86d8b6";
}// if
else {
colors[row, 0] = "#c4c4a4";
}// else
colors[row, 1] = "blue";
colors[row, 2] = "green";
finalColors.push(colors);
}// for
Logger.log(finalColors);
SpreadsheetApp.getActiveSpreadsheet().
getRangeByName("Proef").setBackgrounds(finalColors);
}
Very happy with this, but . . . isn't there a way to directly use the finalColors array? Or is that slower or just not common practice.
I am making a game using Swift and SpriteKit where i move an object to random locations based on an array.
The array that is made up of CGPoints:
let easyArray = [CGPointMake(0,0), CGPointMake(126.6,0), CGPointMake(253.4,0), CGPointMake(0,197.5), CGPointMake(126.7,197.5), CGPointMake(253.4,197.5), CGPointMake(0,395), CGPointMake(126.7,395), CGPointMake(253.4,395)]
I use this function to generate a random number:
func randomNumber(maximum: UInt32) -> Int {
var randomNumber = arc4random_uniform(maximum)
while previousNumber == randomNumber {
randomNumber = arc4random_uniform(maximum)
}
previousNumber = randomNumber
return Int(randomNumber)
}
I used this to move the object based on the random number generated:
let greenEasy = randomNumberNew(9)
let moveSelector = SKAction.moveTo(easyArray[greenEasy], duration: 0)
selector.runAction(moveSelector)
I have done some reading online and found that the "While" condition should make it so that the same random number isn't generate twice in a row. But it still happens.
Can anyone please help me on how to make it so i don't get the same number twice in a row?
The code below doesn't random the same number.
var currentNo: UInt32 = 0
func randomNumber(maximum: UInt32) -> Int {
var randomNumber: UInt32
do {
randomNumber = (arc4random_uniform(maximum))
}while currentNo == randomNumber
currentNo = randomNumber
return Int(randomNumber)
}
I think Larme's suggestion is pretty clever, actually.
easyArray.append(easyArray.removeAtIndex(Int(arc4random_uniform(UInt32(easyArray.count)-1))))
selector.runAction(SKAction.moveTo(easyArray.last!, duration: 0))
I would recommend to not use while() loops with randomizers.
Theoretically it can cause infinite loops in worst case scenario, in more positive scenario it will just take few loops before you get desired results.
Instead I would advice to make an NSArray of all values, remove from this NSArray last randomized element and randomize any of other existing elements from such an array - that is guarantee result after only one randomize iteration.
It can be easily achieved by making NSArray category in Objective-C:
- (id) randomARC4Element
{
if(self.count > 0)
{
return [self objectAtIndex:[self randomIntBetweenMin:0 andMax:self.count-1]];
}
return nil;
}
- (int)randomIntBetweenMin:(int)minValue andMax:(int)maxValue
{
return (int)(minValue + [self randomFloat] * (maxValue - minValue));
}
- (float)randomFloat
{
return (float) arc4random() / UINT_MAX;
}
If you can use linq then you can select a random value that doesn't match the last value. Then for any left over values you can loop through and find valid places to insert them.
It's not the most efficient but it works.
public static List<int> Randomize(List<int> reps, int lastId) {
var rand = new Random();
var newReps = new List<int>();
var tempReps = new List<int>();
tempReps.AddRange(reps);
while (tempReps.Any(x => x != lastId)) {
var validReps = tempReps.FindAll(x => x != lastId);
var i = rand.Next(0, validReps.Count - 1);
newReps.Add(validReps[i]);
lastId = validReps[i];
tempReps.Remove(validReps[i]);
}
while (tempReps.Any()) {
var tempRep = tempReps.First();
bool placed = false;
for (int i = 0; i < newReps.Count; i++) {
if (newReps[i] == tempRep) {
continue;
}
else if ((i < newReps.Count - 1) && (newReps[i + 1] == tempRep)) {
continue;
}
else {
newReps.Insert(i + 1, tempRep);
placed = true;
break;
}
}
if (placed) {
tempReps.Remove(tempRep);
}
else {
throw new Exception("Unable to randomize reps");
}
}
return newReps;
}
Can any1 explain how we can create Excel WITHOUT using INTEROP in c# window service.
So that I can apply styles also to the generating excel as I wish.
Rigin
You can use one of the Excel libraries. I use this C# Excel library.
See also this sample of code:
http://www.easyxls.com/manual/FAQ/export-to-excel-in-dot-net.html
You can create both XLS or XLSX documents.
You can create excel in windows services like below:
public static void GenerateExcel(DataTable DT, string fullFileName, string rptHeader, string SheetName)
{
try
{
var file = new FileInfo(fullFileName);
string currentFileName = System.IO.Path.GetFileName(fullFileName);
ExcelPackage excel = new ExcelPackage(file);
var sheetcreate = excel.Workbook.Worksheets.Add("Sheet1");
//rptHeader = getCaption(rptHeader);
char c = 'A';
c = (char)(((int)c) + DT.Columns.Count - 1);
//sheetcreate.Cells["A1:" + c+"1"].Value = rptHeader;
sheetcreate.Cells["A1:D1"].Value = rptHeader;
sheetcreate.Cells["A1:" + c + "1"].Style.Fill.PatternType = ExcelFillStyle.Solid;
//sheetcreate.Cells["A1:" + c + "1"].Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#c6c6c6"));
sheetcreate.Cells[1, 1, 1, DT.Columns.Count].Merge = true;
sheetcreate.Cells[1, 1, 1, DT.Columns.Count].Style.Font.Bold = true;
int col = 0;
foreach (DataColumn column in DT.Columns)
{
sheetcreate.Cells[2, ++col].Value = column.ColumnName;
sheetcreate.Cells[2, col].Style.Font.Bold = true;
sheetcreate.Cells[2, col].Style.Border.BorderAround(OfficeOpenXml.Style.ExcelBorderStyle.Thin);
sheetcreate.Cells[2, col].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
}
if (DT.Rows.Count > 0)
{
int row = 2;
for (int eachRow = 0; eachRow < DT.Rows.Count; ) //looping each row
{
bool havingText = false;
for (int eachColumn = 1; eachColumn <= col; eachColumn++) //looping each column in a row
{
var eachRowObject = sheetcreate.Cells[row + 1, eachColumn];
eachRowObject.Style.Fill.PatternType = ExcelFillStyle.Solid;
eachRowObject.Value = DT.Rows[eachRow][(eachColumn - 1)].ToString();
if (!havingText) //checking if 'totoa' in string and setting up 'havingText' variable to color it differently
havingText = DT.Rows[eachRow][(eachColumn - 1)].ToString().ToLower().Contains("total");
//Making all cell value to left align
eachRowObject.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
//if (CL.isDecimal(DT.Rows[eachRow][(eachColumn - 1)].ToString())) //if it is number with decimal value make it right align
//{
// eachRowObject.Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;
//}
//eachRowObject.Style.Border.BorderAround(OfficeOpenXml.Style.ExcelBorderStyle.Thin); // adding border to each cells
//if (eachRow % 2 == 0) //alternatively adding color to each cell.
// eachRowObject.Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#e0e0e0"));
//else
// eachRowObject.Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#ffffff"));
}
if (havingText) //if any cell data containt 'total' color complete.
{
for (int eachColumn = 1; eachColumn <= col; eachColumn++)
{
sheetcreate.Cells[row + 1, eachColumn].Style.Fill.PatternType = ExcelFillStyle.Solid;
//sheetcreate.Cells[row + 1, eachColumn].Style.Fill.BackgroundColor.SetColor(System.Drawing.ColorTranslator.FromHtml("#86a9ef"));
}
}
eachRow++;
row++;
}
getLog("batch controller: in loop");
}
getLog("batch controller: 485");
sheetcreate.Cells.AutoFitColumns();
excel.Save();
}
catch (Exception e)
{
getLog("Error while generating excel=>"+e);
}
}
You can download EPPlus from : https://www.nuget.org/packages/EPPlus/