I want to convert the ranges of below fashion to rows and column notations
The example input and the expected output is given below
Input is A1 => Then output is [0,1,0,1]
B1 = [0,1,1,2]
A2 = [1,2,0,1]
C2 = [1,2,2,3]
C12 = [11,12,2,3]
A1:B4 = [0,4,0,2]
C1:D11 = [0,11,2,4]
F32:H43 = [31,43,5,8]
C:F = [null,null,2,6]
30:38 = [29,38,null,null]
76:79 = [75,79,null,null]
AA1:AD15 = [0,15,26,30]
Z2:B1 = [null,null,null,null] or undefined //any invalid range
2:B1 = [null,null,null,null] or undefined //any invalid range
0:0 = [null,null,null,null] or undefined //any invalid range
4-2 = [null,null,null,null] or undefined //any invalid range
6-7d7 = [null,null,null,null] or undefined //any invalid range
The general formula
[startrow-1,endrow,startcol-1,endcol]
30:38 = [startrow-1,endrow,null,null]
76:79 = [startrow-1,endrow,null,null]
C:F = [null,null,2,6]
A1
can also be written as
A1:A1 = [0,1,0,1]
C12
can also be written as
C12:C12 = [11,12,2,3]
My code works for these
A10:B10 //already works
A:B10 //not working so far
A10:B //not working so far
A:B //not working so far
10:10 //not working so far
<!DOCTYPE html>
<html>
<body>
<script>
function fromA1Notation(cell) {
var i, l, chr,
sum = 0,
A = "A".charCodeAt(0),
radix = "Z".charCodeAt(0) - A + 1;
if (typeof cell !== 'string' || !/^[A-Z]+$/.test(cell)) {
throw new Error("Expected column label");
}
for (i = 0, l = cell.length; i < l; i++) {
chr = cell.charCodeAt(i);
sum = sum * radix + chr - A + 1
}
return sum;
}
var input = "A1:B20";
if (input.length > 0 && input.match(/[A-Z]+[0-9]+:[A-Z]+[0-9]+/i) != null) {
var matched = input.match("([A-Za-z]+)([0-9]+):([A-Za-z]+)([0-9]+)");
console.log(JSON.stringify(matched))
if (matched != null) {
a1range = {
a1not: input,
c1: (fromA1Notation(matched[1].toUpperCase()) - 1),
r1: (matched[2] - 1),
c2: fromA1Notation(matched[3].toUpperCase()),
r2: matched[4]
};
if (a1range.c1 >= a1range.c2 || a1range.c1 >= a1range.c2) {
a1range = undefined;
}
console.log(a1range)
}
}
console.log(a1range)
</script>
</body>
</html>
Here is a solution that:
turns 'A1' pattern into 'A1:A1'
matches col, num, ':', col, num
converts col letters into 1-based index
does invalid range check
fixed the start row and start col index to be zero based
function A2N (str) {
return str.split('').reduce((acc, char, idx) => {
return acc += char.charCodeAt(0) - 65 + (idx * 26);
}, 1);
}
[ 'A1', 'B1', 'A2', 'C:F', 'A10:B10', 'A:B10', 'A10:B', 'A:B', '10:10', 'AA1', 'AAA1', 'A', '1', 'B', '20', 'Z9:A1', '#'
].forEach(str => {
let parts = str
.replace(/^(\w+)$/, '$1:$1') // turn 'A1' into 'A1:A1'
.match(/^([A-Z]*)([0-9]*)(?::([A-Z]*)([0-9]*))?$/);
let result = [ null, null, null, null ];
if(parts) {
result = [
parts[2] ? Number(parts[2]) : null,
parts[4] ? Number(parts[4]) : null,
parts[1] ? A2N(parts[1]) : null,
parts[3] ? A2N(parts[3]) : null
];
if(result[0] && result[1] && result[0] > result[1]) {
// invalid range
result[0] = null;
result[1] = null;
}
if(result[2] && result[3] && result[2] > result[3]) {
// invalid range
result[2] = null;
result[3] = null;
}
if(result[0]) {
// zero-based start row
result[0]--;
}
if(result[2]) {
// zero-based start col
result[2]--;
}
}
console.log(str, '==>', result);
});
How to convert a time string like 1m15s to 75s, 75 or 75000 ideally using momentjs.
I attempted to parse that string using new Date('1m1s') but it gives Invalid Date.
I don't want to resort to regex:
const second = (function () {
const countdownStep = '1h1m1s'.match(
/(?:(?<h>\d{0,2})h)?(?:(?<m>\d{0,2})m)?(?:(?<s>\d{0,2})s)?/i
);
return (
(countdownStep.groups.h
? parseInt(countdownStep.groups.h) * 3600
: 0) +
(countdownStep.groups.m
? parseInt(countdownStep.groups.m) * 60
: 0) +
(countdownStep.groups.s ? parseInt(countdownStep.groups.s) : 0)
);
})();
You can use the duration interface of momentjs:
let s = '1m15s';
// convert to duration format and pass to momentjs
let secs = moment.duration('PT' + s.toUpperCase()).as("seconds");
console.log("seconds: ", secs);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
Without library, it could be:
const unit = { s: 1, m: 60, h: 60*60 };
let s = '1m15s';
let secs = s.toLowerCase().match(/\d+./g)
.reduce((acc, p) => acc + parseInt(p) * unit[p.at(-1)], 0);
console.log("seconds: ", secs);
Another approach using plain js:
const getSecondsFromString = (str) => {
const hourIndex = str.indexOf("h")
const minuteIndex = str.indexOf("m")
const secondIndex = str.indexOf("s")
let hours = 0
let minutes = 0
let seconds = 0
if (hourIndex !== -1) {
hours = Number(str.substring(0, hourIndex))
}
if (minuteIndex !== -1) {
if (hourIndex !== -1) {
minutes = Number(str.substring(hourIndex + 1, minuteIndex))
} else {
minutes = Number(str.substring(0, minuteIndex))
}
}
if (secondIndex !== -1) {
if (minuteIndex !== -1) {
seconds = Number(str.substring(minuteIndex + 1, secondIndex))
} else if (hourIndex !== -1) {
seconds = Number(str.substring(hourIndex + 1, secondIndex))
} else {
seconds = Number(str.substring(0, secondIndex))
}
}
return hours * 3600 + minutes * 60 + seconds
}
Another approach without substring/replace, in O(n);
const getSecondsFromTimeString = (timeString) => {
let numberBeforeNextChar = 0;
let seconds = 0;
const symbolToSecondMap = {
"s" : 1,
"m" : 60,
"h" : 60*60,
"d" : 60*60*24
};
for (let i = 0; i < timeString.length; i++) {
let char = timeString.charAt(i);
if((+ char) <= 9 && (+ char) >= 0 ){
numberBeforeNextChar = (numberBeforeNextChar * 10) + parseInt(char);
continue;
}
if(char.toLowerCase() == char.toUpperCase()){
throw "Non alphanumeric symbol encountered";
}
if(symbolToSecondMap[char] === undefined){
throw "Invalid date alphabet encountered";
}
seconds = seconds + (numberBeforeNextChar * symbolToSecondMap[char]);
numberBeforeNextChar = 0;
}
return seconds;
}
console.log(getSecondsFromTimeString('1s'))
console.log(getSecondsFromTimeString('10s'))
console.log(getSecondsFromTimeString('1s4m10d3h'))
console.log(getSecondsFromTimeString('1s4m03h1h'))
console.log(getSecondsFromTimeString('10d'))
I tried this, is it helpful to you
let d = '1H1s';
d = d.toLowerCase();
let sec = 0;
if(d.indexOf('h') > -1) {
if (d.indexOf('m') == -1) {
d = d.substring(0, d.indexOf('h') + 1) +"0m"+d.substring(d.indexOf('h') + 1);
}
}
let newDs = d.replace('h',':').replace('m',':').replace('s','').split(':');
newDs.forEach((v, i) => sec += Math.pow(60, (newDs.length - i - 1)) * v);
console.log(sec);
I have the following code to display in Indian numbering system.
var x=125465778;
var res= x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
Am getting this output :125,465,778.
I need output like this: 12,54,65,778.
Please help me to sort out this problem .
i'm late but i guess this will help :)
you can use Number.prototype.toLocaleString()
Syntax
numObj.toLocaleString([locales [, options]])
var number = 123456.789;
// India uses thousands/lakh/crore separators
document.getElementById('result').innerHTML = number.toLocaleString('en-IN');
// → 1,23,456.789
document.getElementById('result1').innerHTML = number.toLocaleString('en-IN', {
maximumFractionDigits: 2,
style: 'currency',
currency: 'INR'
});
// → ₹1,23,456.79
<div id="result"></div>
<div id="result1"></div>
For Integers:
var x=12345678;
x=x.toString();
var lastThree = x.substring(x.length-3);
var otherNumbers = x.substring(0,x.length-3);
if(otherNumbers != '')
lastThree = ',' + lastThree;
var res = otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + lastThree;
alert(res);
Live Demo
For float:
var x=12345652457.557;
x=x.toString();
var afterPoint = '';
if(x.indexOf('.') > 0)
afterPoint = x.substring(x.indexOf('.'),x.length);
x = Math.floor(x);
x=x.toString();
var lastThree = x.substring(x.length-3);
var otherNumbers = x.substring(0,x.length-3);
if(otherNumbers != '')
lastThree = ',' + lastThree;
var res = otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + lastThree + afterPoint;
alert(res);
Live Demo
Simple way to do,
1. Direct Method using LocalString()
(1000.03).toLocaleString()
(1000.03).toLocaleString('en-IN') # number followed by method
2. using Intl - Internationalization API
The Intl object is the namespace for the ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting.
eg: Intl.NumberFormat('en-IN').format(1000)
3. Using Custom Function:
function numberWithCommas(x) {
return x.toString().split('.')[0].length > 3 ? x.toString().substring(0,x.toString().split('.')[0].length-3).replace(/\B(?=(\d{2})+(?!\d))/g, ",") + "," + x.toString().substring(x.toString().split('.')[0].length-3): x.toString();
}
console.log("0 in indian format", numberWithCommas(0));
console.log("10 in indian format", numberWithCommas(10));
console.log("1000.15 in indian format", numberWithCommas(1000.15));
console.log("15123.32 in indian format", numberWithCommas(15123.32));
if your input is 10000.5,
numberWithCommas(10000.5)
You will get output like this, 10,000.5
For integers only no additional manipulations needed.
This will match every digit from the end, having 1 or more double digits pattern after, and replace it with itself + ",":
"125465778".replace(/(\d)(?=(\d\d)+$)/g, "$1,");
-> "1,25,46,57,78"
But since we want to have 3 in the end, let's state this explicitly by adding extra "\d" before match end of input:
"125465778".replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
-> "12,54,65,778"
Given a number to below function, it returns formatted number in Indian format of digit grouping.
ex: input: 12345678567545.122343
output: 1,23,45,67,85,67,545.122343
function formatNumber(num) {
input = num;
var n1, n2;
num = num + '' || '';
// works for integer and floating as well
n1 = num.split('.');
n2 = n1[1] || null;
n1 = n1[0].replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
num = n2 ? n1 + '.' + n2 : n1;
console.log("Input:",input)
console.log("Output:",num)
return num;
}
formatNumber(prompt("Enter Number",1234567))
https://jsfiddle.net/scLtnug8/1/
I am little late in the game.
But here is the implicit way to do this.
var number = 3493423.34;
console.log(new Intl.NumberFormat('en-IN', { style: "currency", currency: "INR" }).format(number));
if you dont want currency symbol, use it like this
console.log(new Intl.NumberFormat('en-IN').format(number));
The easiest way is just to use Globalize plugin (read more about it here and here):
var value = 125465778;
var formattedValue = Globalize.format(value, 'n');
Try like below, I have found a number formatter Plugin here : Java script number Formatter
By using that i have done the below code, It works fine, Try this, It will help you..
SCRIPT :
<script src="format.20110630-1100.min.js" type="text/javascript"></script>
<script>
var FullData = format( "#,##0.####", 125465778)
var n=FullData.split(",");
var part1 ="";
for(i=0;i<n.length-1;i++)
part1 +=n[i];
var part2 = n[n.length-1]
alert(format( "#0,#0.####", part1) + "," + part2);
</script>
Inputs :
1) 125465778
2) 1234567.89
Outputs :
1) 12,54,65,778
2) 12,34,567.89
Simply use https://osrec.github.io/currencyFormatter.js/
Then all you need is:
OSREC.CurrencyFormatter.format(2534234, { currency: 'INR' });
// Returns ₹ 25,34,234.00
These will format the value in the respective systems.
$(this).replace(/\B(?=(?:\d{3})+(?!\d))/g, ',');
For US number system (millions & billions)
$(this).replace(/\B(?=(?:(\d\d)+(\d)(?!\d))+(?!\d))/g, ',');
For Indian number system (lakhs & crores)
This function can handle float value properly just addition to another answer
function convertNumber(num) {
var n1, n2;
num = num + '' || '';
n1 = num.split('.');
n2 = n1[1] || null;
n1 = n1[0].replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
num = n2 ? n1 + '.' + n2 : n1;
n1 = num.split('.');
n2 = (n1[1]) || null;
if (n2 !== null) {
if (n2.length <= 1) {
n2 = n2 + '0';
} else {
n2 = n2.substring(0, 2);
}
}
num = n2 ? n1[0] + '.' + n2 : n1[0];
return num;
}
this function will convert all function to float as it is
function formatAndConvertToFloatFormat(num) {
var n1, n2;
num = num + '' || '';
n1 = num.split('.');
if (n1[1] != null){
if (n1[1] <= 9) {
n2 = n1[1]+'0';
} else {
n2 = n1[1]
}
} else {
n2 = '00';
}
n1 = n1[0].replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
return n1 + '.' + n2;
}
Improvised Slopen's approach above, Works for both int and floats.
function getIndianFormat(str) {
str = str.split(".");
return str[0].replace(/(\d)(?=(\d\d)+\d$)/g, "$1,") + (str[1] ? ("."+str[1]): "");
}
console.log(getIndianFormat("43983434")); //4,39,83,434
console.log(getIndianFormat("1432434.474")); //14,32,434.474
Based on Nidhinkumar's question i have checked the above answers and
while handling negative numbers the output won't be correct for eg: -300 it should display as -300 but the above answers will display it as -,300 which is not good so i have tried with the below code which works even during the negative cases.
var negative = input < 0;
var str = negative ? String(-input) : String(input);
var arr = [];
var i = str.indexOf('.');
if (i === -1) {
i = str.length;
} else {
for (var j = str.length - 1; j > i; j--) {
arr.push(str[j]);
}
arr.push('.');
}
i--;
for (var n = 0; i >= 0; i--, n++) {
if (n > 2 && (n % 2 === 1)) {
arr.push(',');
}
arr.push(str[i]);
}
if (negative) {
arr.push('-');
}
return arr.reverse().join('');
Improvising #slopen's answer with decimal support and test cases.
Usage: numberToIndianFormat(555555.12) === "5,55,555.12"
utils.ts
export function numberToIndianFormat(x: number): string {
if (isNaN(x)) {
return "NaN"
} else {
let string = x.toString();
let numbers = string.split(".");
numbers[0] = integerToIndianFormat(parseInt(numbers[0]))
return numbers.join(".");
}
}
function integerToIndianFormat(x: number): string {
if (isNaN(x)) {
return "NaN"
} else {
let integer = x.toString();
if (integer.length > 3) {
return integer.replace(/(\d)(?=(\d\d)+\d$)/g, "$1,");
} else {
return integer;
}
}
}
utils.spec.ts
describe('numberToIndianFormat', () => {
it('nan should output NaN', () => {
expect(numberToIndianFormat(Number.NaN)).toEqual("NaN")
});
describe('pure integer', () => {
it('should leave zero untouched', () => {
expect(numberToIndianFormat(0)).toEqual("0")
});
it('should leave simple numbers untouched', () => {
expect(numberToIndianFormat(10)).toEqual("10")
});
it('should add comma at thousand place', () => {
expect(numberToIndianFormat(5555)).toEqual("5,555")
});
it('should add comma at lakh place', () => {
expect(numberToIndianFormat(555555)).toEqual("5,55,555")
});
it('should add comma at crore place', () => {
expect(numberToIndianFormat(55555555)).toEqual("5,55,55,555")
});
});
describe('with fraction', () => {
it('should leave zero untouched', () => {
expect(numberToIndianFormat(0.12)).toEqual("0.12")
});
it('should leave simple numbers untouched', () => {
expect(numberToIndianFormat(10.12)).toEqual("10.12")
});
it('should add comma at thousand place', () => {
expect(numberToIndianFormat(5555.12)).toEqual("5,555.12")
});
it('should add comma at lakh place', () => {
expect(numberToIndianFormat(555555.12)).toEqual("5,55,555.12")
});
it('should add comma at crore place', () => {
expect(numberToIndianFormat(55555555.12)).toEqual("5,55,55,555.12")
});
});
})
Indian money format function
function indian_money_format(amt)
{
amt=amt.toString();
var lastThree = amt.substring(amt.length-3);
var otherNumbers = amt.substring(0,amt.length-3);
if(otherNumbers != '')
lastThree = ',' + lastThree;
var result = otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ",") + lastThree;
alert(result)
return result;
}
indian_money_format(prompt("Entry amount",123456))