【问题标题】:Find the min/max along a single axis of a 3D javascript array沿 3D javascript 数组的单轴查找最小值/最大值
【发布时间】:2018-12-11 01:46:54
【问题描述】:

我有一个 3 维数组,其中包含 n 个多边形集合的最小/最大纬度边界集。我想从所有多边形的集合中找到最小和最大坐标。

我下面的解决方案有效,但我觉得它很笨拙。我真正的问题是:有没有办法获得沿轴的最小值/最大值,以便它返回[ [lat_min, lon_min], [lat_max, lon_max] ] 形式的数组,而无需分别对每个点执行reduce 函数?

// Where bounds is an array of latlon bounds for n polygons:
// bounds = [
//   [ [min_lat_1, min_lon_1], [max_lat_1, max_lon_1] ],
//   ...
//   [ [min_lat_n, min_lon_n], [max_lat_n, max_lon_n] ]
// ]
const x1 = bounds.reduce((min, box) => {
  return box[0][0] < min ? box[0][0] : min;
}, bounds[0][0][0]);
const y1 = bounds.reduce((min, box) => {
  return box[0][1] < min ? box[0][1] : min;
}, bounds[0][0][1]);
const x2 = bounds.reduce((max, box) => {
  return box[1][0] > max ? box[1][0] : max;
}, bounds[0][1][0]);
const y2 = bounds.reduce((max, box) => {
  return box[1][1] > max ? box[1][1] : max;
}, bounds[0][1][1]);

编辑:到目前为止,我得到的响应改进了我的代码,但到目前为止,没有什么能完全达到我的期望。

一些进一步的背景/规范:我更熟悉 python/numpy,您可以在其中指定跨任何轴应用函数。在这种情况下,我想沿轴 3(即深度轴)应用我的函数。但是,由于我不只是在寻找最小值/最大值,因此我创建的函数还需要根据索引返回一个函数(最小值或最大值)。这在Javascript中根本不可行吗?似乎 es6 中应该有一些优雅的组合来完成工作。

【问题讨论】:

    标签: javascript arrays ecmascript-6


    【解决方案1】:

    您可以在Math.minMath.max 上使用.apply 来传递一个数字数组以立即进行比较。

    您还可以使用.map 提取坐标的 X 或 Y。

    const bounds = [
       [ [1, 2], [3, 999] ],
       [ [-999, 6], [7, 8] ],
       [ [9, 10], [11, 12] ]
    ]
    
    // `pos` determines whether it should get the min set or the max set
    const getXOf = pos => bounds.map(a => a[pos][0]);
    const getYOf = pos => bounds.map(a => a[pos][1]);
    
    // Using .apply, you can compare an array of numbers at once.
    const findMin = arr => Math.min.apply(null, arr);
    const findMax = arr => Math.max.apply(null, arr);
    
    // For clarity only
    const MIN = 0;
    const MAX = 1;
    
    const min_x = findMin(getXOf(MIN));
    const min_y = findMin(getYOf(MIN));
    const max_x = findMax(getXOf(MAX));
    const max_y = findMax(getYOf(MAX));
    
    console.log(min_x, min_y, max_x, max_y);

    【讨论】:

    • 我喜欢这种将 getXOf 和 getYOf 简化为基于位置的函数的方法。这更接近我希望找到的东西,而且我比我的解决方案更喜欢这个。它确实让我想知道这里是否有一种方法可以创建一个函数,该函数根据位置返回最小/最大函数,该函数可以映射到整个数组。
    • @nomeq 是的,当然有办法。您可以尝试自己先使用上述内容作为参考,如果您在谷歌搜索后仍无法使其工作,请发布另一个问题
    【解决方案2】:

    您可以将所有 reduce 合并为一个并返回数组 [ [lat_min, lon_min], [lat_max, lon_max] ],如下所示:

    const bounds = [
      [ [ 0.0, 0.1 ], [ 0.6, 0.7 ] ],
      [ [ 0.2, 0.3 ], [ 0.8, 0.9 ] ],
      [ [ 0.4, 0.5 ], [ 0.1, 0.2 ] ]
    ];
    
    const minMax = bounds.reduce((current, box) => {
      const minLat = box[0][0] < current[0][0] ? box[0][0] : current[0][0];
      const minLon = box[0][1] < current[0][1] ? box[0][1] : current[0][1];
      const maxLat = box[1][0] > current[1][0] ? box[1][0] : current[1][0];
      const maxLon = box[1][1] > current[1][1] ? box[1][1] : current[1][1];
      return [ [ minLat, minLon ], [ maxLat, maxLon ] ]
    }, bounds[0]);
    
    console.log('combined reduce:', minMax);

    以下是您的参考代码:

    const bounds = [
      [ [ 0.0, 0.1 ], [ 0.6, 0.7 ] ],
      [ [ 0.2, 0.3 ], [ 0.8, 0.9 ] ],
      [ [ 0.4, 0.5 ], [ 0.1, 0.2 ] ]
    ];
    
    const x1 = bounds.reduce((min, box) => {
      return box[0][0] < min ? box[0][0] : min;
    }, bounds[0][0][0]);
    const y1 = bounds.reduce((min, box) => {
      return box[0][1] < min ? box[0][1] : min;
    }, bounds[0][0][1]);
    const x2 = bounds.reduce((max, box) => {
      return box[1][0] > max ? box[1][0] : max;
    }, bounds[0][1][0]);
    const y2 = bounds.reduce((max, box) => {
      return box[1][1] > max ? box[1][1] : max;
    }, bounds[0][1][1]);
    
    console.log('separate reduce:', [ [ x1, y1 ], [ x2, y2 ] ]);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      • 2015-09-09
      • 2019-07-10
      • 2020-08-23
      • 1970-01-01
      • 2021-09-15
      • 2021-07-31
      相关资源
      最近更新 更多