沿着3D JavaScript数组的单轴查找最小值/最大值

时间:2018-12-11 01:46:54

标签: javascript arrays ecmascript-6

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

我下面的解决方案有效,但是我发现它很笨拙。我真正的问题是:是否有一种方法可以获取沿轴的最小值/最大值,以使其返回形式为[ [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中应该有一些优雅的组合可以完成工作。

2 个答案:

答案 0 :(得分:1)

您可以在.applyMath.min上使用Math.max传递一个数字数组,以便立即进行比较。

您还可以使用.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);

答案 1 :(得分:0)

您可以将所有的reduces合并为一个,然后返回数组[ [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 ] ]);