У меня есть объект javascript, который имеет время суток и представление с плавающей точкой этого. Я случайно поместил их в неправильном порядке, поэтому я быстро перевернул их, но теперь поплавки являются строками.
Вот более короткая версия объекта (ДО того, как он был перевернут):
const conversion_chart = {
1:'12:00 AM',
0.04: '1:00 AM',
0.08: '2:00 AM',
0.13: '3:00 AM',
0.17: '4:00 AM',
0.21: '5:00 AM',
0.25: '6:00 AM',
0.29: '7:00 AM',
0.33: '8:00 AM',
0.38: '9:00 AM',
0.42: '10:00 AM',
0.46: '11:00 AM',
0.5: '12:00 PM',
}
А теперь с этой функцией:
function flip(o){
var ret = {};
for(var key in o){
ret[o[key]] = key;
}
return ret;
}
console.log(flip(conversion_chart));
Он возвращает:
'12:00 AM': '1',
'1:00 AM': '0.04',
'2:00 AM': '0.08',
'3:00 AM': '0.13',
'4:00 AM': '0.17',
'5:00 AM': '0.21',
'6:00 AM': '0.25',
'7:00 AM': '0.29',
'8:00 AM': '0.33',
'9:00 AM': '0.38',
'10:00 AM': '0.42',
'11:00 AM': '0.46',
'12:00 PM': '0.5'
Это в основном то, что я намеревался сделать, за исключением новых значений (то есть: 1, 0.04, 0.08
и т. Д., Которые все еще должны быть плавающими).
Как я могу получить новые значения с плавающей точкой?
Спасибо за помощь!
3 ответа
Вы можете использовать parseFloat
:
function flip(o){
var ret = {};
for(var key in o){
ret[o[key]] = parseFloat(key);
}
return ret;
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat
Одним из возможных решений является использование Unary Plus оператор MDN
говорит:
унарный плюс - это самый быстрый и предпочтительный способ преобразования чего-либо в число, поскольку он не выполняет никаких других операций с числом.
В любом случае, вы должны заметить, что объект keys
всегда является строкой, а не numbers
, если мы говорим о них type
.
const conversion_chart = {
1: '12:00 AM',
0.04: '1:00 AM',
0.08: '2:00 AM',
0.13: '3:00 AM',
0.17: '4:00 AM',
0.21: '5:00 AM',
0.25: '6:00 AM',
0.29: '7:00 AM',
0.33: '8:00 AM',
0.38: '9:00 AM',
0.42: '10:00 AM',
0.46: '11:00 AM',
0.5: '12:00 PM',
}
function flip(o)
{
var ret = {};
for (var key in o)
{
ret[o[key]] = +key;
}
return ret;
}
console.log(flip(conversion_chart));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Кроме того, вы можете использовать Array.reduce () над Object.entries ( ) тоже:
const conversion_chart = {
1: '12:00 AM',
0.04: '1:00 AM',
0.08: '2:00 AM',
0.13: '3:00 AM',
0.17: '4:00 AM',
0.21: '5:00 AM',
0.25: '6:00 AM',
0.29: '7:00 AM',
0.33: '8:00 AM',
0.38: '9:00 AM',
0.42: '10:00 AM',
0.46: '11:00 AM',
0.5: '12:00 PM',
}
const flip = (o) => Object.entries(o).reduce(
(acc, [k, v]) => ({...acc , [v]: +k}),
{}
);
console.log(flip(conversion_chart));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
При взгляде на ваш вопрос выглядело, как будто вы пытаетесь преобразовать время, указанное в 12-часовой нотации, в дробное число дня. Выполнение этого с помощью справочной таблицы быстро приводит к гигантской таблице, и легко допустить ошибки.
Другой способ решить эту проблему - вместо этого рассчитать значения. При таком подходе он может обрабатывать все 1440 минут в течение дня без справочной таблицы.
Ниже вы найдете две функции: time12hToDayfraction
, которые преобразуют 12-часовые часы в дневную долю, и dayFractionToTime12h
, чтобы преобразовать дневную часть в 12-часовые часы.
Код сильно комментируется, чтобы помочь вам понять, что он делает. Если вы удалите все комментарии, вы увидите, что код довольно компактен.
function time12hToDayfraction(input) {
if ( typeof input !== 'string') throw TypeError('Invalid type. Expexted string');
// Using regex validate a valid time and to split it into hours, minutes and AM/PM
// ^ Match start of string
// (1[0-2]|[0-9]) Match 1 follwed by a 0,1 or 2, or 0,1,2,3,4,5,6,7,8 or 9
// : Match the colon
// ([0-5][0-9]) Match 0,1,2,3,4 or 5 followed by 0,1,2,3,4,5,6,7,8 or 9.
// ([AP]M) Match A or P followed by M
// $ Match end of string
// toUpperCase converts the string to upper case. I could have made the regex
// case insensitive, but when calculating the hours below I need to know if
// if was AM or PM, and now I can make a simple string comparison instead of
// a case insensitive comparison.
const parts = input.toUpperCase().match(/^(1[0-2]|[0-9]):([0-5][0-9]) ([AP]M)$/);
if (!parts) throw Error('Invalid format');
// Convert string in parts to numbers
const value = {
// parts[1] is the hours.
// parts[2] is the minutes
// parts[3] is "AM" or "PM"
// Using reminder % to make 12 = 0.
// Using conditional (ternary) operator to decide if 0 or 12 should be added.
hours : ( +parts[1] % 12 ) + ( parts[3] === 'PM' ? 12 : 0 ), // Convert to 24 hours
minutes : +parts[2]
}
// This returns MIDNIGHT (12:00 AM) as 0, and NOON (12:00 PM) as 0.5
return ( value.hours + ( value.minutes / 60 ) ) / 24
// I saw that you example had "12:00 AM" as 1. If you want "12:00 AM" as 1,
// and "12:01 AM" as slmost zero, replace the line above with:
// return (( value.hours + ( value.minutes / 60 ) ) / 24) || 1
}
// Converts a day fraction to time 12 h
function dayFractionToTime12h(input) {
if ( typeof input !== 'number') throw TypeError('Invalid type. Expexted number');
if ( input < 0 || input > 1 ) throw RangeError('Input shuld be 0 - 1');
const clock24 = input * 24; // Convert input to 24 hour clock.
const value = {
// Convert 24-hour-clock to 12-hour-clock by using
// reminder % 12 to get a value between 0-11 and locical or-operator
// to convert 0 to 12.
hours : (Math.floor( clock24 ) % 12) || 12,
// Calculate minutes
minutes : Math.round(clock24 * 60) % 60,
apm : clock24 < 12 ? 'AM' : 'PM'
}
return `${value.hours}:${value.minutes.toString().padStart(2,'0')} ${value.apm}`;
}
// Example
[
'12:00 AM', '12:30 AM', '1:00 AM', '2:00 AM', '3:00 AM', '4:00 AM', '5:00 AM',
'6:00 AM', '7:00 AM', '8:00 AM', '9:00 AM', '10:00 AM', '11:00 AM',
'12:00 PM', '1:00 PM', '2:00 PM', '3:00 PM', '4:00 PM', '5:00 PM',
'6:00 PM', '7:00 PM', '8:00 PM', '9:00 PM', '10:00 PM', '11:00 PM',
'11:59 PM'
].forEach( input => {
const frac = time12hToDayfraction(input);
const time = dayFractionToTime12h(frac);
if (input != time) throw Error(`input!=time "${input}" "${time}"`);
console.log( input, frac.toFixed(2), time );
});
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.