turnHoursToMinutes
неправильно обрабатывает случай, когда значение duration
уже равно Number
или undefined
. Посмотрите эту аннотированную версию вашей функции
function turnHoursToMinutes(minutesArr) {
// >>> consider just returning the mapped Array
return minutesArr.map(currentItem => {
let stringtime = currentItem.duration;
if (typeof stringtime === "string" &&
stringtime !== null &&
stringtime !== "" && stringtime !== undefined) {
let strnumbers = stringtime.match(/\d+/g);
let numbers = strnumbers.map(Number);
let minutes = 0;
if (stringtime.includes("h") && stringtime.includes("min")) {
minutes = (numbers[0] * 60) + numbers[1];
} else if (stringtime.includes("h")) {
minutes = numbers[0] * 60;
} else if (stringtime.includes("min")) {
minutes = numbers[0];
}
currentItem.duration = minutes;
// >>> no need for the spread and no need to return currentItem here
// return {...currentItem};
}
// >>> no need for this case, because it's already a number
// and that was what you wanted in the first place
//!else if (typeof stringtime === "number") {
// >>> this is why your test fails. You are still in the 'map' lambda
// and should return currentItem, not the propery
//! return currentItem.duration;
//!}
//!else if (typeof stringtime === "undefined") {
// >>> same: should've returned currentItem
//! return currentItem.duration = 0;
//!}
// >>> the above can be simplified to
currentItem.duration = currentItem.duration || 0;
// >>> now you've covered all, so return currentItem
return currentItem;
});
}
В любом случае, я позволил себе упростить ваш код. Этот рефакторинг извлекает код для определения числового значения (в минутах) duration
, которое, в свою очередь, может быть использовано при (пере) отображении объекта фильмов.
const calcMinutesFromDurationString = str =>
str ? String(str).split(" ")
.reduce( (acc, val) =>
acc + ( val.endsWith("h") ? 60 * parseInt(val) : parseInt(val)), 0)
: 0;
const mapMoviesWithDurationInMinutes = item =>
( { ...item, duration: calcMinutesFromDurationString(item.duration) || 0 } );
console.log(getMovies().map(mapMoviesWithDurationInMinutes));
// ----------------
function getMovies() {
return [
{
title: 'The Shawshank Redemption',
year: '1994',
director: 'Frank Darabont',
duration: '2h 22min',
genre: ['Crime', 'Drama'],
rate: '9.3'
},
{
title: 'The Godfather',
year: '1972',
director: 'Francis Ford Coppola',
duration: '2h 55min',
genre: ['Crime', 'Drama'],
rate: '9.2'
},
{
title: 'The Godfather: Part II',
year: '1974',
director: 'Francis Ford Coppola',
duration: '3h 22min',
genre: ['Crime', 'Drama'],
rate: '9.0'
},
// added 1 without 'duration'
// actually the movie lasts 15 minutes :P
{
title: 'Capital Execution',
year: '1903',
director: 'Peter Elfelt',
genre: ['Drama'],
rate: 'n/a'
},
// added 1 with 'duration' = 'unknown' string
{
title: 'The Lamb',
year: '1915',
director: 'W. Christy Cabanne',
genre: ['Comedy', 'Western'],
rate: 'n/a',
duration: 'unknown'
},
// added 1 with 'duration' = 71 (minutes)
{
title: 'Frankenstein',
year: '1931',
director: 'Robert Florey',
genre: ['Drama', 'Horror'],
rate: 'n/a',
duration: 71
},
];
}
.as-console-wrapper {
max-height: 100% !important
}
Более того: теперь вы можете проверять конвертацию независимо
const calcMinutesFromDurationString = str =>
str ? String(str).split(" ")
.reduce((acc, val) =>
acc + (val.endsWith("h") ? 60 * parseInt(val) : parseInt(val)), 0) || 0 :
0;
console.log(`Converted values\n calcMinutesFromDurationString("5h 0min") => ${
calcMinutesFromDurationString("5h 0min")}\n calcMinutesFromDurationString("") => ${
calcMinutesFromDurationString("")}\n calcMinutesFromDurationString("unknown") => ${
calcMinutesFromDurationString("unknown")}\n calcMinutesFromDurationString(65) => ${
calcMinutesFromDurationString(65)}\n calcMinutesFromDurationString("65min") => ${
calcMinutesFromDurationString("65min")}\n calcMinutesFromDurationString("1h") => ${
calcMinutesFromDurationString("1h")}\n calcMinutesFromDurationString() => ${
calcMinutesFromDurationString()}\n calcMinutesFromDurationString(null) => ${
calcMinutesFromDurationString(null)}\n calcMinutesFromDurationString("120") => ${
calcMinutesFromDurationString("120")}`);
const isNumber = val => typeof val === "number" ? "yes" : "nope";
console.log(`Are we talking numbers here?
calcMinutesFromDurationString("5h 0min") => ${
isNumber(calcMinutesFromDurationString("5h 0min"))}
calcMinutesFromDurationString("") => ${
isNumber(calcMinutesFromDurationString(""))}
calcMinutesFromDurationString("unknown") => ${
isNumber(calcMinutesFromDurationString("unknown"))}
calcMinutesFromDurationString(65) => ${
isNumber(calcMinutesFromDurationString(65))}
calcMinutesFromDurationString("65min") => ${
isNumber(calcMinutesFromDurationString("65min"))}
calcMinutesFromDurationString("1h") => ${
isNumber(calcMinutesFromDurationString("1h"))}
calcMinutesFromDurationString() => ${
isNumber(calcMinutesFromDurationString())}
calcMinutesFromDurationString(null) => ${
isNumber(calcMinutesFromDurationString(null))}
calcMinutesFromDurationString("120") => ${
isNumber(calcMinutesFromDurationString("120"))}`);
.as-console-wrapper {
max-height: 100% !important
}