Reputation: 12334
If anyone can think of a better title I'm open to it. Anyway I've been struggling to get this to produce just the right output for several hours now but haven't got it to work in all situations.
Simply put I have a list of fixed dates including every day between a range, and I need to produce an array of the gaps between the dates that are missing in the provided date array.
So in the example below:
fixed dates: [2019-09-23, 2019-09-24, 2019-09-25, 2019-09-26, 2019-09-27, 2019-09-28, 2019-09-29]
given dates: [2019-09-23, 2019-09-24, 2019-09-26, 2019-09-27, 2019-09-28]
The first number is 0 since there is no gap between the opening date and the provided date. Then from there it is just the gaps between each date:
[0, 1, 2, 1, 1, 2]
To make it a little clearer how we get these numbers:
[2019-09-23, 2019-09-24, 2019-09-25, 2019-09-26, 2019-09-27, 2019-09-28, 2019-09-29]
[2019-09-23, 2019-09-24, 2019-09-26, 2019-09-27, 2019-09-28]
0 1 2 1 1 2
I got this to work ok after a while but there is one other factor, there is data associated with each date and if there are two or more the same in a row, we also skip a day. Note that the data and given dates have the same length and thus the same indices. So with two values in a row in the example below, we skip that as well so the desired output would be as follows:
fixed dates: [2019-09-23, 2019-09-24, 2019-09-25, 2019-09-26, 2019-09-27, 2019-09-28, 2019-09-29]
given dates: [2019-09-23, 2019-09-24, 2019-09-26, 2019-09-27, 2019-09-28]
given data: [82.0, 85.5, 85.5, 85.0, 86.5]
desired output: [0, 1, 3, 1*, 1, 2]
I won't post what I tried since I don't think it is that great and moreover will influence the answers. But I tried anything from finding the difference between the dates, to using a simple increment in a for loop which increases each time a date is skipped.
If there is a difference between the initial fixed date and the first given date then the first number in the array will not be zero, it will be the difference.
Here is some data and the desired outputs:
fixed dates: [2019-09-23, 2019-09-24, 2019-09-25, 2019-09-26, 2019-09-27, 2019-09-28, 2019-09-29, 2019-09-30, 2019-10-01, 2019-10-02, 2019-10-03, 2019-10-04]
given dates: [2019-09-23, 2019-09-24, 2019-09-26, 2019-09-27, 2019-09-28, 2019-10-01]
given data: [82.0, 85.0, 84.0, 85.0, 86.5, 84.0]
desired output: [0, 1, 2, 1, 1, 3, 3]
fixed dates: [2019-09-09, 2019-09-10, 2019-09-11, 2019-09-12, 2019-09-13, 2019-09-14, 2019-09-15, 2019-09-16, 2019-09-17, 2019-09-18]
given dates: [2019-09-10, 2019-09-11, 2019-09-12, 2019-09-13, 2019-09-15, 2019-09-17]
given data: [85.0, 81.0, 85.0, 85.0, 83.0, 85.5]
desired output: [1, 1, 1, 3, 2*, 2, 2]
* skipped
Must skip otherwise there will be too many elements.
fixed dates: [2019-09-09, 2019-09-10, 2019-09-11, 2019-09-12, 2019-09-13, 2019-09-14, 2019-09-15, 2019-09-16, 2019-09-17, 2019-09-18, 2019-09-19, 2019-09-20, 2019-09-21, 2019-09-22]
given dates: [2019-09-10, 2019-09-11, 2019-09-12, 2019-09-13, 2019-09-15, 2019-09-17, 2019-09-18, 2019-09-19, 2019-09-20, 2019-09-21]
given data: [85.0, 81.0, 85.0, 85.0, 83.0, 85.5, 85.0, 86.0, 85.0, 84.5]
desired output: [1, 1, 1, 3, 2*, 2, 1, 1, 1, 1, 2]
* skipped
Must skip otherwise there will be too many elements.
fixed dates: [2019-09-09, 2019-09-10, 2019-09-11, 2019-09-12, 2019-09-13, 2019-09-14, 2019-09-15, 2019-09-16, 2019-09-17, 2019-09-18, 2019-09-19, 2019-09-20, 2019-09-21, 2019-09-22]
given dates: [2019-09-10, 2019-09-11, 2019-09-12, 2019-09-13, 2019-09-15, 2019-09-16, 2019-09-17, 2019-09-18, 2019-09-19, 2019-09-20, 2019-09-21]
given data: [85.0, 81.0, 85.0, 85.0, 83.0, 83.5, 85.5, 85.0, 85.0, 85.0, 84.5]
desired output: [1, 1, 1, 3, 2*, 1, 1, 1, 3, 2*, 1*, 2]
* skipped
Must skip otherwise there will be too many elements.
I guess it may be a bit too difficult but I thought I'd post it anyway and see if someone can come up with a nice solution.
Upvotes: 2
Views: 121
Reputation: 350725
For the purpose of extending gaps when values remain unchanged, and accounting for the dates for which there is no data, I would suggest iterating over the fixed data in reverse order.
I provide here an implementation in JavaScript.
function getGaps(fixedDates, dates, values) {
let j = dates.length-1;
let result = Array(dates.length+1).fill(0);
let gap = 0;
for (let i = fixedDates.length - 1; i >= 0; i--) { // Go backwards
gap++; // Count every entry in fixedDates
if (j >= 0 && fixedDates[i] === dates[j]) {
result[j + 1] = gap;
// Only reset gap when value is different from previous
if (j === 0 || values[j] !== values[j - 1]) gap = 0;
j--;
}
}
result[0] = gap;
return result;
}
let tests = [[
["2019-09-23", "2019-09-24", "2019-09-25", "2019-09-26", "2019-09-27", "2019-09-28", "2019-09-29"],
["2019-09-23", "2019-09-24", "2019-09-26", "2019-09-27", "2019-09-28"],
[82.0, 85.5, 85.5, 85.0, 86.5]
], [
["2019-09-23", "2019-09-24", "2019-09-25", "2019-09-26", "2019-09-27", "2019-09-28", "2019-09-29", "2019-09-30", "2019-10-01", "2019-10-02", "2019-10-03", "2019-10-04"],
["2019-09-23", "2019-09-24", "2019-09-26", "2019-09-27", "2019-09-28", "2019-10-01"],
[82.0, 85.0, 84.0, 85.0, 86.5, 84.0]
], [
["2019-09-09", "2019-09-10", "2019-09-11", "2019-09-12", "2019-09-13", "2019-09-14", "2019-09-15", "2019-09-16", "2019-09-17", "2019-09-18"],
["2019-09-10", "2019-09-11", "2019-09-12", "2019-09-13", "2019-09-15", "2019-09-17"],
[85.0, 81.0, 85.0, 85.0, 83.0, 85.5]
], [
["2019-09-09", "2019-09-10", "2019-09-11", "2019-09-12", "2019-09-13", "2019-09-14", "2019-09-15", "2019-09-16", "2019-09-17", "2019-09-18", "2019-09-19", "2019-09-20", "2019-09-21", "2019-09-22"],
["2019-09-10", "2019-09-11", "2019-09-12", "2019-09-13", "2019-09-15", "2019-09-17", "2019-09-18", "2019-09-19", "2019-09-20", "2019-09-21"],
[85.0, 81.0, 85.0, 85.0, 83.0, 85.5, 85.0, 86.0, 85.0, 84.5]
], [
["2019-09-09", "2019-09-10", "2019-09-11", "2019-09-12", "2019-09-13", "2019-09-14", "2019-09-15", "2019-09-16", "2019-09-17", "2019-09-18", "2019-09-19", "2019-09-20", "2019-09-21", "2019-09-22"],
["2019-09-10", "2019-09-11", "2019-09-12", "2019-09-13", "2019-09-15", "2019-09-16", "2019-09-17", "2019-09-18", "2019-09-19", "2019-09-20", "2019-09-21"],
[85.0, 81.0, 85.0, 85.0, 83.0, 83.5, 85.5, 85.0, 85.0, 85.0, 84.5]
], [
["2019-09-30", "2019-10-01", "2019-10-02", "2019-10-03", "2019-10-04", "2019-10-05", "2019-10-06"],
["2019-10-01", "2019-10-05", "2019-10-06"],
[84.0, 85.5, 85.0],
]];
for (let test of tests) console.log(JSON.stringify(getGaps(...test)));
There are 6 test cases here. The one that you presented first in your question, and 4 other examples you listed all together, and an additional case you mentioned in comments below.
The output of the second case (first of your block of 4) is different in the final number, but it is my understanding it should be like this.
Upvotes: 1