谷歌应用程序脚本:根据另一个2D数组的最近时间戳过滤一个2D阵列



我有两个2D数组;两者都包含时间戳和浮点值。Array1包含数百个时间戳值对,而Array2通常只包含约10个时间戳-值对。

我试图将Array1与Array2进行比较,只想为最接近Array2中时间戳的时间戳保留Array1的时间戳值配对。

Array1 = {[59.696, 2020-12-30T00:00:00.000Z], 
          [61.381, 2020-12-30T00:15:00.000Z], 
          [59.25, 2020-12-30T00:30:00.000Z],
          [57.313, 2020-12-30T00:45:00.000Z],...}
Array2 = {[78.210, 2020-12-30T00:06:00.000Z], 
          [116.32, 2020-12-30T00:39:00.000Z],...}

因此,在上面的这些数组示例中,我希望Array1被过滤为:

Array1 = {[59.696, 2020-12-30T00:00:00.000Z], 
          [57.313, 2020-12-30T00:45:00.000Z],...}

因为这些时间戳与Array2中的时间戳最匹配。我曾尝试在谷歌脚本的两张纸上为两列实现Find matches中建议的代码,但无法使其发挥作用,否则我也找不到一个巧妙的时间戳匹配解决方案。

非常感谢您的帮助。如果我需要编辑或添加更多信息到我的问题中,请告诉我。

目标

给定两个阵列:

Array1 = [
  [59.696, "2020-12-30T00:00:00.000Z"], 
  [61.381, "2020-12-30T00:15:00.000Z"], 
  [59.25, "2020-12-30T00:30:00.000Z"],
  [57.313, "2020-12-30T00:45:00.000Z"]
]
Array2 = [
  [78.210, "2020-12-30T00:06:00.000Z"],
  [116.32, "2020-12-30T00:39:00.000Z"]
]

目标是使Array2中的每个项目与Array1中最近的日期相匹配。因此,上面示例的结果数组将是2个项目。如果Array2有100个项目,而Array1有1000个项目,则得到的数组将是100个项目。

我假设Array1中的每个项目只能使用一次。我还假设数组中的第一个项,即浮点值,在计算中被忽略,但与日期保持在一起,并包含在输出中。

脚本

function filterClosestTimes(array1, array2) {
  // Initializing "maps" to keep track of the differences
  // closest, will contain the final pairs used
  // differences, is used to decide which pair gets used
  // positions used, is so that the same pair in array 1
  // doesn't get used twice.
  closest = []
  differences = []
  positionsUsed = []
  // For each member of array2
  array2.forEach((pair, i) => {
    // Initializing a date object
    targetDate = new Date(pair[1])
    // Initializing the position of the current index in the
    // tracking arrays.
    closest.push(null)
    differences.push(Infinity)
    positionsUsed.push(null)
    // Going through each member of array 1
    array1.forEach((subpair, j) => {
      // First checking if the position has already been used
      if (positionsUsed.includes(j)) return
      //initializing date
      dateToTest= new Date(subpair[1])
      // checking difference between the currently testing date
      // of array 2
      difference = Math.abs(targetDate - dateToTest)
      // Checking if it is the date with the smallest difference
      // if so, setting the position in the tracking arrays.
      // These values will likely be overwritten many times until
      // the date with the least difference is found.
      if (differences[i] > difference) {
        differences[i] = difference
        closest[i] = subpair
        positionsUsed[i] = j
      }
    })
  })
  return closest
}
function test(){
  Logger.log(filterClosestTimes(Array1, Array2))
}

运行test返回:

[["59.696, 2020-12-30T00:00:00.000Z"], ["57.313, 2020-12-30T00:45:00.000Z"]]

备注

这种算法涉及到将一个数组的每个元素与另一个数组中的几乎每个元素进行检查,因此速度可能会变慢。不过,如果你只处理数百个值,并与Array2中的~10进行比较,那就没问题了。请注意,这种方法具有O(n^2(时间复杂性。这意味着,随着比较次数的增加,完成操作所需的时间呈指数级增长。如果你试图将数万与数万进行比较,那么会有一个明显的等待!

参考文献

  • JS Date对象
  • 时间复杂性

最新更新