Converting 1M to 1000000 Elegantly

Converting 1M to 1000000 elegantly

Here's my own attempt:

market.cap[ , cap1 := {
sf <- gsub("[0-9]", "", cap)
as.numeric(gsub("[^0-9]", "", cap)) * 1000 ^ (2 + (sf == "B"))}]

The following approach may prove faster since it doesn't need to waste effort on running cap through a regex twice:

market.cap[ , cap1 := {
x<- do.call("rbind", strsplit(cap, split = "(?=[BM])", perl = TRUE))
as.numeric(x[ , 1L]) * 1000 ^ (2 + (x[ , 2L] == "B"))}]

And the following may prove fastest since tstrsplit has been optimized in data.table:

market.cap[ , cap1 := {
x <- tstrsplit(cap, split = "(?=[BM])", perl = TRUE)
as.numeric(x[[1L]]) * 1000 ^ (2 + (x[[2]] == "B"))}]

Converting abbreviated numbers into numbers in R

Try gsub() on the letters:

df$variableName <- gsub("M", "000000", df$variableName)
df$variableName <- gsub("K", "000", df$variableName)

and so forth...

Maybe convert the class when you're done class(df$variable) <- "numeric".

Formatting long numbers as strings

I don't think there's a built-in function that does that. You'll have to roll your own, e.g.:

def human_format(num):
magnitude = 0
while abs(num) >= 1000:
magnitude += 1
num /= 1000.0
# add more suffixes if you need them
return '%.2f%s' % (num, ['', 'K', 'M', 'G', 'T', 'P'][magnitude])

print('the answer is %s' % human_format(7436313)) # prints 'the answer is 7.44M'

Convert long number into abbreviated string in JavaScript, with a special shortness requirement

I believe ninjagecko's solution doesn't quite conform with the standard you wanted. The following function does:

function intToString (value) {
var suffixes = ["", "k", "m", "b","t"];
var suffixNum = Math.floor((""+value).length/3);
var shortValue = parseFloat((suffixNum != 0 ? (value / Math.pow(1000,suffixNum)) : value).toPrecision(2));
if (shortValue % 1 != 0) {
shortValue = shortValue.toFixed(1);
}
return shortValue+suffixes[suffixNum];
}

For values greater than 99 trillion no letter will be added, which can be easily fixed by appending to the 'suffixes' array.

Edit by Philipp follows: With the following changes it fits with all requirements perfectly!

function abbreviateNumber(value) {
var newValue = value;
if (value >= 1000) {
var suffixes = ["", "k", "m", "b","t"];
var suffixNum = Math.floor( (""+value).length/3 );
var shortValue = '';
for (var precision = 2; precision >= 1; precision--) {
shortValue = parseFloat( (suffixNum != 0 ? (value / Math.pow(1000,suffixNum) ) : value).toPrecision(precision));
var dotLessShortValue = (shortValue + '').replace(/[^a-zA-Z 0-9]+/g,'');
if (dotLessShortValue.length <= 2) { break; }
}
if (shortValue % 1 != 0) shortValue = shortValue.toFixed(1);
newValue = shortValue+suffixes[suffixNum];
}
return newValue;
}

Format a number as 2.5K if a thousand or more, otherwise 900

Sounds like this should work for you:

function kFormatter(num) {    return Math.abs(num) > 999 ? Math.sign(num)*((Math.abs(num)/1000).toFixed(1)) + 'k' : Math.sign(num)*Math.abs(num)}    console.log(kFormatter(1200)); // 1.2kconsole.log(kFormatter(-1200)); // -1.2kconsole.log(kFormatter(900)); // 900console.log(kFormatter(-900)); // -900

How to go about formatting 1200 to 1.2k in java

Here is a solution that works for any long value and that I find quite readable (the core logic is done in the bottom three lines of the format method).

It leverages TreeMap to find the appropriate suffix. It is surprisingly more efficient than a previous solution I wrote that was using arrays and was more difficult to read.

private static final NavigableMap<Long, String> suffixes = new TreeMap<> ();
static {
suffixes.put(1_000L, "k");
suffixes.put(1_000_000L, "M");
suffixes.put(1_000_000_000L, "G");
suffixes.put(1_000_000_000_000L, "T");
suffixes.put(1_000_000_000_000_000L, "P");
suffixes.put(1_000_000_000_000_000_000L, "E");
}

public static String format(long value) {
//Long.MIN_VALUE == -Long.MIN_VALUE so we need an adjustment here
if (value == Long.MIN_VALUE) return format(Long.MIN_VALUE + 1);
if (value < 0) return "-" + format(-value);
if (value < 1000) return Long.toString(value); //deal with easy case

Entry<Long, String> e = suffixes.floorEntry(value);
Long divideBy = e.getKey();
String suffix = e.getValue();

long truncated = value / (divideBy / 10); //the number part of the output times 10
boolean hasDecimal = truncated < 100 && (truncated / 10d) != (truncated / 10);
return hasDecimal ? (truncated / 10d) + suffix : (truncated / 10) + suffix;
}


Test code

public static void main(String args[]) {
long[] numbers = {0, 5, 999, 1_000, -5_821, 10_500, -101_800, 2_000_000, -7_800_000, 92_150_000, 123_200_000, 9_999_999, 999_999_999_999_999_999L, 1_230_000_000_000_000L, Long.MIN_VALUE, Long.MAX_VALUE};
String[] expected = {"0", "5", "999", "1k", "-5.8k", "10k", "-101k", "2M", "-7.8M", "92M", "123M", "9.9M", "999P", "1.2P", "-9.2E", "9.2E"};
for (int i = 0; i < numbers.length; i++) {
long n = numbers[i];
String formatted = format(n);
System.out.println(n + " => " + formatted);
if (!formatted.equals(expected[i])) throw new AssertionError("Expected: " + expected[i] + " but found: " + formatted);
}
}

Correct way to convert size in bytes to KB, MB, GB in JavaScript

From this: (source)


Unminified and ES6'ed: (by the community)

function formatBytes(bytes, decimals = 2) {
if (!+bytes) return '0 Bytes'

const k = 1024
const dm = decimals < 0 ? 0 : decimals
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']

const i = Math.floor(Math.log(bytes) / Math.log(k))

return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
}

// Demo code
document.body.innerHTML += `<input type="text" oninput="document.querySelector('p').innerHTML=formatBytes(this.value)" value="1000"><p>1000 Bytes</p>`

Unformat disk size strings

Something like this?

$ echo "1K + 10M" | sed -e "s/K/*1024/g;s/M/*1024*1024/" | bc
10486784

Edit:

sed -e 's/t/kg/i;s/g/km/i;s/m/kk/i;s/k/*1000/ig;s/b//i' | bc

Convert an entire range to uppercase without looping through all the cells

Is there a method I can use to convert the whole range in one line?

Yes you can convert without looping. Try this

Sub Sample()
[A1:A20] = [INDEX(UPPER(A1:A20),)]
End Sub

Alternatively, using a variable range, try this:

Sub Sample()
Dim rng As Range
Set rng = Range("A1:A20")
rng = Evaluate("index(upper(" & rng.Address & "),)")
End Sub

As per your example

W.Range("A1:A20") = [index(upper(A1:A20),)]

Explanation

There are two parts to [A1:A20] = [INDEX(UPPER(A1:A20),)]

PART 1

As shown above, [A1:A20] is nothing but just a short way of writing Range("A1:A20")

PART 2

[INDEX(UPPER(A1:A20),)]

Index and Upper are worksheet functions. So you can use Application.Worksheetfunction.Index() but since we don't have an equivalent of UPPER like Application.Worksheetfunction.UPPER(), we can only write it as [cell] = [UPPER(cell)]

Now with that line we are instructing VBA to return an array and this is where INDEX comes into play. (As we are aware, there are two forms of the INDEX function: the array form and the reference form.) By not specifying a row or a column of the array, we are simply letting Excel know that we want the whole array. (Mentioned in VBA help as well) So basically what we are doing is converting each cell in [A1:A20] into uppercase



Related Topics



Leave a reply



Submit