Найти мин / макс вдоль одной оси трехмерного массива JavaScript - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть 3-мерный массив, который содержит наборы минимальных / максимальных границ для набора из n полигонов.Я хочу найти минимальную и максимальную координаты из набора всех многоугольников.

Мое решение ниже работает, но я нахожу его неловким.Мой реальный вопрос: есть ли способ получить минимум / максимум вдоль оси, чтобы он возвращал массив в форме [ [lat_min, lon_min], [lat_max, lon_max] ] без выполнения функции уменьшения для каждой точки отдельно?

// 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, то есть оси глубины.Но, поскольку я не просто ищу min / max, созданная мной функция также должна возвращать функцию (Min или Max) в зависимости от индекса.Разве это просто невозможно в Javascript?Просто кажется, что в es6 должна быть какая-то элегантная комбинация, которая сделает работу.

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Вы можете использовать .apply на Math.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);
0 голосов
/ 11 декабря 2018

Вы можете объединить все сокращения только в одном и вернуть массив [ [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 ] ]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...