如何在Apps Script中实现MATCH函数查找小于目标日期的最近日期索引
Apps Script 实现最接近且小于指定日期的索引查找
效率最优方案(适用于升序排列的日期数组)
如果你的日期数组是升序排列(和给出的示例一致),优先使用二分查找实现,时间复杂度为O(logn),性能完全对标Google Sheets原生MATCH函数,远高于遍历查找的效率。
function findNearestSmallerDate(dateArr, searchDate) { // 统一转成时间戳比较,避免日期对象的类型兼容问题 const timestampList = dateArr.map(item => new Date(item).getTime()); const targetTimestamp = new Date(searchDate).getTime(); let left = 0; let right = timestampList.length - 1; let matchIndex = -1; // 无符合条件元素时返回-1 while (left <= right) { const mid = Math.floor((left + right) / 2); if (timestampList[mid] < targetTimestamp) { // 当前元素符合小于目标的条件,记录索引后继续向右找更接近目标的元素 matchIndex = mid; left = mid + 1; } else { // 当前元素大于等于目标,向左缩小范围 right = mid - 1; } } // 示例要求返回1开始的索引,如需0开始的索引直接返回matchIndex即可 return matchIndex === -1 ? -1 : matchIndex + 1; }
测试验证
用你给出的示例参数调用:
const testArr = ["8/1/21", "8/5/22", "8/5/23"]; const testSearchDate = "9/17/22"; console.log(findNearestSmallerDate(testArr, testSearchDate)); // 输出结果为2,和示例要求一致
未排序日期数组适配方案
如果你的日期数组没有提前排序,可以先绑定原始索引再排序后做二分查找:
function findNearestSmallerDateUnordered(dateArr, searchDate) { const targetTimestamp = new Date(searchDate).getTime(); // 绑定原始索引后按时间戳升序排序 const indexedDateList = dateArr.map((item, index) => ({ ts: new Date(item).getTime(), originIndex: index })).sort((a, b) => a.ts - b.ts); let left = 0; let right = indexedDateList.length - 1; let matchIndex = -1; while (left <= right) { const mid = Math.floor((left + right) / 2); if (indexedDateList[mid].ts < targetTimestamp) { matchIndex = indexedDateList[mid].originIndex; left = mid + 1; } else { right = mid - 1; } } return matchIndex === -1 ? -1 : matchIndex + 1; }
内容的提问来源于stack exchange,提问作者Kim Hopkins
相关产品推荐
相关产品推荐

