convert array with strings of minute format to seconds format - javascript

["4", "5.67", "1:45.67", "4:43.45"]
I have this string array and i want to convert all of the strings to numbers with seconds format so it will become something like this
[4, 5.67, 105.67, 283.45]
how can i do it?
function hmsToSecondsOnly(str) {
var p = str.split(':'),
s = 0, m = 1;
while (p.length > 0) {
s += m * parseInt(p.pop(), 10);
m *= 60;
}
return s;
}
I found this but it seems to only work in MM:SS format like 1:40 but i want convert strings in x:xx.xx format

You can try using map() like the following way:
var data = ["4", "5.67", "1:45.67", "4:43.45"];
data = data.map(function(item){
//split to get the hour
var a1 = item.split(':');
//split to get the seconds
var a2 = item.split('.');
//check the length
if(a1.length > 1){
//split to get minutes
var t = a1[1].split('.');
//calculate, cast and return
return +((a1[0]*60 + +t[0]) + '.' + a2[a2.length - 1]);
}
else return +item;
});
console.log(data);

You could map the formatted time values.
const
data = ["4", "5.67", "1:45.67", "4:43.45"],
result = data.map(time => time
.split(':')
.map(Number)
.reduce((m, s) => m * 60 + s)
);
console.log(result);

Another simple solution with RegEx.
const input = ["4", "5.67", "1:45.67", "4:43.45"]
const result = input.map(ele => ele.replace(/^(\d+):(\d+[.]\d*)$/, (m, g1, g2) => `${g1 * 60 + parseFloat(g2)}`));
console.log(result)

Related

Math operations from string using Javascript

I am trying to find a simple way to perform a set of javascript math operations without using eval() function. Example: 1+2x3x400+32/2+3 and it must follow the PEMDAS math principle. This is what I have, but it doesn't work exactly it should.
function mdas(equation) {
let operations = ["*", "/", "+", "-"];
for (let outerCount = 0; outerCount < operations.length; outerCount++) {
for (let innerCount = 0; innerCount < equation.length; ) {
if (equation[innerCount] == operations[outerCount]) {
let operationResult = runOperation(equation[innerCount - 1], operations[outerCount], equation[innerCount + 1]);
var leftSideOfEquation = equation.substr(0, equation.indexOf(innerCount - 1));
var rightSideOfEquation = equation.substr(equation.indexOf(innerCount), equation.length);
var rightSideOfEquation = rightSideOfEquation.replace(rightSideOfEquation[0],String(operationResult));
equation = leftSideOfEquation + rightSideOfEquation;
innerCount = 0;
}
else {
innerCount++;
}
}
}
return "Here is it: " + equation; //result of the equation
}
If you don't want to use a complete library like mathjs - and you don't want to tackle creating your own script which would involve: lexical analysis, tokenization, syntax analysis, recursive tree parsing, compiling and output...
the simplest banal suggestion: Function
const calc = s => Function(`return(${s})`)();
console.log( calc("1+2*3*400+32/2+3") ); // 2420
console.log( calc("-3*-2") ); // 6
console.log( calc("-3 * + 1") ); // -3
console.log( calc("-3 + -1") ); // -4
console.log( calc("2 * (3 + 1)") ); // 8
My take at a custom MDAS
Here I created a Regex to retrieve operands and operators, accounting for negative values: /(-?[\d.]+)([*\/+-])?/g.
Firstly we need to remove any whitespace from our string using str.replace(/ /g , "")
Using JavaScript's String.prototype.matchAll() we can get a 2D array with all the matches as [[fullMatch, operand, operator], [.. ] we can than further flatten it using Array.prototype.flat()
Having that flattened array, we can now filter it using Array.prototype.filter() to remove the fullMatch -es returned by the regular expression and remove the last undefined value.
Define a calc Object with the needed operation functions
Iterate over the MDAS groups */ and than +- as regular expressions /\/*/ and /+-/
Consume finally the array of matches until only one array key is left
let str = "-1+2 * 3*+400+-32 /2+3.1"; // 2386.1
str = str.replace(/ +/g, ""); // Remove all spaces!
// Get operands and operators as array.
// Remove full matches and undefined values.
const m = [...str.matchAll(/(-?[\d.]+)([*\/+-])?/g)].flat().filter((x, i) => x && i % 3);
const calc = {
"*": (a, b) => a * b,
"/": (a, b) => a / b,
"+": (a, b) => a + b,
"-": (a, b) => a - b,
};
// Iterate by MDAS groups order (first */ and than +-)
[/[*\/]/, /[+-]/].forEach(expr => {
for (let i = 0; i < m.length; i += 2) {
let [a, x, b] = [m[i], m[i + 1], m[i + 2]];
x = expr.exec(x);
if (!x) continue;
m[i] = calc[x.input](parseFloat(a), parseFloat(b)); // calculate and insert
m.splice(i + 1, 2); // remove operator and operand
i -= 2; // rewind loop
}
});
// Get the last standing result
console.log(m[0]); // 2386.1
It's a little hacky, but you can try something like this:
var eqs = [
'1+2*3*4+1+1+3',
'1+2*3*400+32/2+3',
'-5+2',
'3*-2',
];
for(var eq in eqs) { console.log(mdas(eqs[eq])); }
function mdas(equation) {
console.log(equation);
var failsafe = 100;
var num = '(((?<=[*+-])-|^-)?[0-9.]+)';
var reg = new RegExp(num + '([*/])' + num);
while(m = reg.exec(equation)) {
var n = (m[3] == "*") ? m[1]*m[4] : m[1]/m[4];
equation = equation.replace(m[0], n);
if(failsafe--<0) { return 'failsafe'; }
}
var reg = new RegExp(num + '([+-])' + num);
while(m = reg.exec(equation)) {
var n = (m[3] == "+") ? 1*m[1] + 1*m[4] : m[1]-m[4];
equation = equation.replace(m[0], n);
if(failsafe--<0) { return 'failsafe'; }
}
return equation;
}

add leading zero to simple timestamp addition JavaScript function

I am trying to write a javascript function to sum up two timestamp strings, like 00:04:02 and 00:05:43
I have this function which works, but returns a value like: 0:9:45, I'm trying to improve it so there is a leading zero for the minutes section so it looks more like: 0:09:45 but im having trouble doing so and was wondering if anyone could help me:
function sum(date1, date2){
date1 = date1.split(":");
date2 = date2.split(":");
const result = [];
date1.reduceRight((carry,num, index) => {
const max = [24,60,60][index];
const add = +date2[index];
result.unshift( (+num+add+carry) % max );
return Math.floor( (+num + add + carry) / max );
},0);
return result.join(":");
}
console.log(sum('00:05:43', '00:04:02'))
Pad each digit?
return result.map(r => String(r).padStart(2, "0")).join(":");
If you use the built-in Date methods, you don't need to parse times or do math yourself.
'use strict';
function sumTimestamps(a, b) {
const [A, B] = [a, b].map((x) => new Date('1970-01-01T' + x + '.000Z'));
return new Date(A.getTime() + B.getTime()).toUTCString().split(' ')[4];
}
const sum = sumTimestamps('00:04:02', '00:05:43');
console.log(sum);
// => 00:09:45

How to distinguish time from am and pm in the value of a variable?

I have the following values.
var list = "09:05, 10:05, 12:30, 16:30 , ... , ..."
The type of values ​​in the list is a regular string, not an object.
Based on this value, I want to divide from 0 to 12 am and from 13 to 23 pm.
Therefore, the result I want is as follows.(If you check the log value)
var am = am 09:05 , am 10:05
var pm = pm 12:30 , pm 16:30
It may be a simple question, but it is a very difficult problem for me as a script novice.
Please help me.
Create a sort function first
var sort = ( a, b ) => convertToMin( a ) - convertToMin( b );
var convertToMin = ( a ) => ( items = a.split( ":" ).map( Number ), items[ 0 ] * 60 + items[ 1 ] );
Now use reduce to segregate the array
var output = list.reduce( (a,b) => //using reduce to iterate, a is the accumulator and b is item in array for current iteration
( convertToMin(b) > 12*60 ? a.pm.push( b ) : a.am.push( b ), a ) ,
{ am :[], pm : [] }) ; //accumulator is initialized to { am :[], pm : [] }
output.am.sort( sort );
output.pm.sort( sort );
Demo
var list = ["09:05", "10:05", "12:30", "16:30"];
var sort = (a, b) => convertToMin(a) - convertToMin(b);
var convertToMin = (a) => (items = a.split(":").map(Number), items[0] * 60 + items[1]);
var output = list.reduce((a, b) =>
(convertToMin(b) > 12 * 60 ? a.pm.push(b) : a.am.push(b), a), {
am: [],
pm: []
});
output.am.sort(sort);
output.pm.sort(sort);
console.log(output);
Here's what I'd do to solve this problem.
Separate the values in the string into an array. I'd Google javascript split string into array. Nothing wrong with Googling stuff; even seasoned devs have to do it all the time! At least I do. :)
Then create a for loop that goes through each element of the array. A good search for how to do that is javascript for loop array.
Then for each element, split the string again (this time by the :).
Then convert the first part into a number (javascript convert string
to integer) and see whether it is bigger or smaller than 12.
You could adjusted value with am/pm time and sort it to the wanted array.
function format(v) { return ('0' + v).slice(-2); }
function getM(t) {
var v = t.split(':');
return (v[0] < 12 ? 'am' : 'pm') + ' ' + [v[0] % 12 || 12, v[1]].map(format).join(':');
}
var list = '09:05, 10:05, 12:30, 16:30',
am = [],
pm = []
result = { am: am, pm: pm };
list
.split(', ')
.map(getM)
.forEach(function (s) {
result[s.slice(0, 2)].push(s);
});
console.log(am);
console.log(pm);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Split the items using the appropriate separator, process them with a cycle then join them with the appropriate separator
var items = list.split(", ");
var ams = [];
var pms = [];
for (var index = 0; index < list.length; index++) {
var isPM = ((list[index].substring(0, 2) >= 12);
var currentArray = window[isPM ? "pms" : "ams"];
var found = false;
var val = (isPM ? "pm" : "am") + " " + items[index];
for (var innerIndex = 0; (!found) && (innerIndex < currentArray.length); innerIndex++) {
if (currentArray[innerIndex] > val) {
found = true;
currentArray.splice(innerIndex, 0, val);
}
}
if (!found) currentArray.push(val);
}
var am = ams.join(" , ");
var pm = pms.join(" , ");
Try with .split method like this,
Updated without jQuery
var list = "09:05, 10:05, 12:30, 16:30";
var options = list.split(',').map(time => {
h = time.split(':')[0];
return parseInt(h) >= 12 ? 'pm ' + time : 'am ' + time;
})
console.log(options);

Javascript comma between seconds

I'm trying to fix this but I can't figure out where I need to start. I using an timer for a banner to play a game and the timer is in seconds with 4 digits. Now, I would like to have a comma between the seconds so it look like this: 13,80 instead of this: 1380. How can I make sure there will be a comma in the seconds?
Here is my code:
var x = new clsStopwatch();
var $time;
var clocktimer;
function pad(num, size) {
var s = "0000" + num;
return s.substr(s.length - size);
}
function formatTime(time) {
var s = ms = 0;
var newTime = '';
time = time % (60 * 60 * 1000);
m = Math.floor( time / (60 * 1000) );
time = time % (24 * 1000);
s = Math.floor( time / 45 + 3800);
newTime = pad(s,4) ;
return newTime;
Use like this:
var str = 1234;
console.log(str.substr(0,2)+','+str.substr(2)); //will print 12,34
Ur code will become:
function pad(num, size) {
var s = "0000" + num;
var str = s.substr(s.length - size);
return str.substr(0,2)+','+str.substr(2);
}
var myNumber = 123;
var myArray = myNumber.toString().split(""); // ["1", "2", "3"]
while (myArray.length < 4) {
myArray.unshift("0"); // ["0", "1", "2", "3"];
}
myArray.splice(2, 0, ","); // second position, take none out, insert comma
// ["0, "1", ",", "2", "3"];
console.log(myArray.join("")); // myArray.join("") === "01,23"
Not the most elegant solution, but it works
//takes a number
//e.g. 9104 returns 91,04
function addComma(number){
var frm = String(number);
return number > 99 ? frm.substring(0, frm.length-2) + ',' + frm.substring(frm.length-2, frm.length) : "0," + frm
}

generate 4 digit random number using substring

I am trying to execute below code:
var a = Math.floor(100000 + Math.random() * 900000);
a = a.substring(-2);
I am getting error like undefined is not a function at line 2, but when I try to do alert(a), it has something. What is wrong here?
That's because a is a number, not a string. What you probably want to do is something like this:
var val = Math.floor(1000 + Math.random() * 9000);
console.log(val);
Math.random() will generate a floating point number in the range [0, 1) (this is not a typo, it is standard mathematical notation to show that 1 is excluded from the range).
Multiplying by 9000 results in a range of [0, 9000).
Adding 1000 results in a range of [1000, 10000).
Flooring chops off the decimal value to give you an integer. Note that it does not round.
General Case
If you want to generate an integer in the range [x, y), you can use the following code:
Math.floor(x + (y - x) * Math.random());
This will generate 4-digit random number (0000-9999) using substring:
var seq = (Math.floor(Math.random() * 10000) + 10000).toString().substring(1);
console.log(seq);
I adapted Balajis to make it immutable and functional.
Because this doesn't use math you can use alphanumeric, emojis, very long pins etc
const getRandomPin = (chars, len)=>[...Array(len)].map(
(i)=>chars[Math.floor(Math.random()*chars.length)]
).join('');
//use it like this
getRandomPin('0123456789',4);
$( document ).ready(function() {
var a = Math.floor(100000 + Math.random() * 900000);
a = String(a);
a = a.substring(0,4);
alert( "valor:" +a );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
Your a is a number. To be able to use the substring function, it has to be a string first, try
var a = (Math.floor(100000 + Math.random() * 900000)).toString();
a = a.substring(-2);
You can get 4-digit this way .substring(startIndex, length), which would be in your case .substring(0, 4). To be able to use .substring() you will need to convert a to string by using .toString(). At the end, you can convert the resulting output into integer by using parseInt :
var a = Math.floor(100000 + Math.random() * 900000)
a = a.toString().substring(0, 4);
a = parseInt(a);
alert(a);
https://jsfiddle.net/v7dswkjf/
The problem is that a is a number. You cannot apply substring to a number so you have to convert the number to a string and then apply the function.
DEMO: https://jsfiddle.net/L0dba54m/
var a = Math.floor(100000 + Math.random() * 900000);
a = a.toString();
a = a.substring(-2);
$(document).ready(function() {
var a = Math.floor((Math.random() * 9999) + 999);
a = String(a);
a = a.substring(0, 4);
});
// It Will Generate Random 5 digit Number & Char
const char = '1234567890abcdefghijklmnopqrstuvwxyz'; //Random Generate Every Time From This Given Char
const length = 5;
let randomvalue = '';
for ( let i = 0; i < length; i++) {
const value = Math.floor(Math.random() * char.length);
randomvalue += char.substring(value, value + 1).toUpperCase();
}
console.log(randomvalue);
function getPin() {
let pin = Math.round(Math.random() * 10000);
let pinStr = pin + '';
// make sure that number is 4 digit
if (pinStr.length == 4) {
return pinStr;
} else {
return getPin();
}
}
let number = getPin();
Just pass Length of to number that need to be generated
await this.randomInteger(4);
async randomInteger(number) {
let length = parseInt(number);
let string:string = number.toString();
let min = 1* parseInt( string.padEnd(length,"0") ) ;
let max = parseInt( string.padEnd(length,"9") );
return Math.floor(
Math.random() * (max - min + 1) + min
)
}
I've created this function where you can defined the size of the OTP(One Time Password):
generateOtp = function (size) {
const zeros = '0'.repeat(size - 1);
const x = parseFloat('1' + zeros);
const y = parseFloat('9' + zeros);
const confirmationCode = String(Math.floor(x + Math.random() * y));
return confirmationCode;
}
How to use:
generateOtp(4)
generateOtp(5)
To avoid overflow, you can validate the size parameter to your case.
Numbers don't have substring method. For example:
let txt = "123456"; // Works, Cause that's a string.
let num = 123456; // Won't Work, Cause that's a number..
// let res = txt.substring(0, 3); // Works: 123
let res = num.substring(0, 3); // Throws Uncaught TypeError.
console.log(res); // Error
For Generating random 4 digit number, you can utilize Math.random()
For Example:
let randNum = (1000 + Math.random() * 9000).toFixed(0);
console.log(randNum);
This is quite simple
const arr = ["one", "Two", "Three"]
const randomNum = arr[Math.floor(Math.random() * arr.length)];
export const createOtp = (): number => {
Number(Math.floor(1000 + Math.random() * 9000).toString());
}

Categories