I have object, keys are dates, before dot are months, after are years:
const dataObj = {
'01.2015': 0.01,
'02.2015': 0.10,
'03.2015': 0.05,
'04.2015': 0.25,
// ...
}
the function takes two dates and return an array with objects containing values from the dataObj
interface Point {
date: string;
value: number;
}
type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
type Day = `${Digit}${Digit}`;
type Month =
| '01'
| '02'
// ...
| '11'
| '12';
type Year = '2015' | '2016' | '2017';
type DateString = `${Day}.${Month}.${Year}`;
type MonthDateString = `${Month}.${Year}`;
function count(firstDate: DateString, secondDate: DateString): Point[] {
const result: Point[] = [];
let currentDate = firstDate.slice(3) as MonthDateString;
// loop through dataObj and push in result
return result // [{date: '01.2015', value: 0.01}, {...}, ...]
}
How to loop through dataObj? I tried for loop
for(let i = currentDate; i !== secondDate.slice(3); )
but have no idea what to do with final-expression, how to update counter variable, pass next key(string with date) from dataObj.
CodePudding user response:
There is some confusion in regards to the expected output. The function count
needs to return a Point
array which is an object array where each object has two props namely date
(a string) and value
(number, floating-point per inline-comments in the code).
It is assumed that the OP requires to find key-value pairs in dataObj
such that the key (ie, month-year) is between firstDate
and secondDate
(which are parameters to count
function).
Based on this assumption, the below code may achieve the desired objective (to generate an array of Point
elements).
const isGreaterOrEqual = (dtOne: MonthDateString, dtTwo: MonthDateString) : Boolean => {
const getYear = (dt: MonthDateString) : string => dt.slice(3);
const getMonth = (dt: MonthDateString) : string => dt.substring(0, 2);
return ((getYear(dtOne) > getYear(dtTwo)) ||
(getYear(dtOne) === getYear(dtTwo) &&
getMonth(dtOne) >= getMonth(dtTwo)
)
);
};
function count(firstDate: DateString, secondDate: DateString): Point[] {
let beginDate = firstDate.slice(3) as MonthDateString;
let endDate = secondDate.slice(3) as MonthDateString;
return (
Object.entries(dataObj)
.filter(([k, v]) => isGreaterOrEqual(k as MonthDateString, beginDate) && isGreaterOrEqual(endDate, k as MonthDateString))
.map(([k, v]) => ({ date: k, value: v} as Point))
);
};
console.log(count( "01.01.2015" as DateString, "01.02.2015" as DateString));
TS Playground: Link here
CodePudding user response:
Some examples below:
for (let key in dataObj) {
console.log(key, dataObj[key]);
}
for (let [key, value] of Object.entries(dataObj)) {
console.log(key, value);
}
If you want to have and update counter variable:
let keys = Object.keys(dataObj);
for (let i = 0; i < keys.length; i ) {
console.log(i, keys[i], dataObj[keys[i]]);
}