Поиск повторяющихся максимальных значений в матрице

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

Вот что у меня есть до сих пор:

        let findColumnMaxValue = (i) => {
         let coord = [];
         let maxValue = 0;
         for (let j = 0; j < this.field.length; j++) {
            if (this.field[i][j].dst > maxValue) {
                maxValue = this.field[i][j].dst;
            }
        }

        getMaxValueCoord(maxValue, coord, i);
        return coord;
    }

Здесь я нахожу максимальное значение для каждой строки каждого столбца.

        let getMaxValueCoord = (max, a, i) => {
         for (let j = 0; j < this.field.length; j++) {
            if (this.field[i][j].dst === max) {
                a.push({x: i, y: j})
            }
        }
    }

и в этой функции, после нахождения максимума, я сравниваю каждую строку каждого столбца с максимальным значением и помещаю координаты объекта в массив, если он соответствует условию.

    findHighestDensityCells() {
     let arr = []; 
     for (let i = 0; i < this.field.length; i++) {
         arr.push(findColumnMaxValue(i));
     }

     return [].concat(...arr);
}

Теперь, когда у меня есть массив всех координат максимального значения объекта для каждого столбца, я хочу, чтобы этот массив содержал только максимальные значения, включая дубликаты, в основном повторяя многое из того, что я сделал выше.

То, что я написал выше, похоже, занимает слишком много кода, чтобы решить эту простую проблему. Существуют ли другие методы, которые я мог бы использовать, чтобы уменьшить объем кода?

РЕДАКТИРОВАТЬ

Данные представляют собой простой объект options = { dst: 0 } со значением, которое обновляется другой функцией. Поэтому все строки в столбцах содержат вышеуказанный объект, каждый с разными значениями. Итак, моя матрица может выглядеть так:

 2 3 4 5 6 6 5 4 3 2
 3 4 5 6 7 7 6 5 4 3
 4 5 6 7 8 8 7 6 5 4
 5 6 3 4 9 9 4 3 2 1
 6 7 3 4 9 9 4 3 2 1
 6 7 3 4 5 5 4 3 2 1
 5 6 3 4 5 5 4 3 2 1
 4 6 3 4 5 5 4 3 2 1
 3 5 3 4 5 5 4 3 2 1
 2 4 3 4 5 5 4 3 2 1

Желаемый результат - получить все максимальные значения в матрице в виде координат, включая дубликаты. В приведенном выше примере это будет [9,9,9,9].


person As above so below    schedule 04.09.2017    source источник
comment
Возможный дубликат Получить наибольшее значение в многомерном массиве javascript или кофескрипт   -  person bamtheboozle    schedule 04.09.2017
comment
если вы просто хотите уменьшить размер кода, посмотрите на функции array.map, array.reduce или Math.max, которые вам помогут. если бы вы могли добавить пример ввода массива mutli D, другим было бы легче вам помочь   -  person Shyam Babu    schedule 04.09.2017
comment
Не могли бы вы добавить свою матрицу данных и желаемый результат?   -  person sergdenisov    schedule 04.09.2017
comment
не забудьте добавить некоторые данные и желаемый результат.   -  person Nina Scholz    schedule 04.09.2017


Ответы (2)


Попробуйте немного магии, используя Array.prototype.reduce(), выражение функции стрелки, Math.max(), оператор распространения, Array.prototype.map(), Array.prototype.concat(), _ 5_:

const maxArray = matrix.reduce((maxArray, row, rowIndex) => {
  const max = Math.max(0, ...row.map(e => e.dst));

  return maxArray.concat(
    row.map(
      (e, i) => ({x: i, y: rowIndex, dst: e.dst})
    ).filter(e => e.dst === max)
  );
}, []);

const maxOfAll = Math.max(0, ...maxArray.map(e => e.dst));

const filteredMaxArray = maxArray.filter(
  e => e.dst === maxOfAll
).map(e => ({x: e.x, y: e.y}));

const matrix = [
  [{dst: 2}, {dst: 3}, {dst: 4}, {dst: 5}, {dst: 6}, {dst: 6}, {dst: 5}, {dst: 4}, {dst: 3}, {dst: 2}],
  [{dst: 3}, {dst: 4}, {dst: 5}, {dst: 6}, {dst: 7}, {dst: 7}, {dst: 6}, {dst: 5}, {dst: 4}, {dst: 3}],
  [{dst: 4}, {dst: 5}, {dst: 6}, {dst: 7}, {dst: 8}, {dst: 8}, {dst: 7}, {dst: 6}, {dst: 5}, {dst: 4}],
  [{dst: 5}, {dst: 6}, {dst: 3}, {dst: 4}, {dst: 9}, {dst: 9}, {dst: 4}, {dst: 3}, {dst: 2}, {dst: 1}],
  [{dst: 6}, {dst: 7}, {dst: 3}, {dst: 4}, {dst: 9}, {dst: 9}, {dst: 4}, {dst: 3}, {dst: 2}, {dst: 1}],
  [{dst: 6}, {dst: 7}, {dst: 3}, {dst: 4}, {dst: 5}, {dst: 5}, {dst: 4}, {dst: 3}, {dst: 2}, {dst: 1}],
  [{dst: 5}, {dst: 6}, {dst: 3}, {dst: 4}, {dst: 5}, {dst: 5}, {dst: 4}, {dst: 3}, {dst: 2}, {dst: 1}],
  [{dst: 4}, {dst: 6}, {dst: 3}, {dst: 4}, {dst: 5}, {dst: 5}, {dst: 4}, {dst: 3}, {dst: 2}, {dst: 1}],
  [{dst: 3}, {dst: 5}, {dst: 3}, {dst: 4}, {dst: 5}, {dst: 5}, {dst: 4}, {dst: 3}, {dst: 2}, {dst: 1}],
  [{dst: 2}, {dst: 4}, {dst: 3}, {dst: 4}, {dst: 5}, {dst: 5}, {dst: 4}, {dst: 3}, {dst: 2}, {dst: 1}],
];

const maxArray = matrix.reduce((maxArray, row, rowIndex) => {
  const max = Math.max(0, ...row.map(e => e.dst));
  
  return maxArray.concat(
    row.map(
      (e, i) => ({x: i, y: rowIndex, dst: e.dst})
    ).filter(e => e.dst === max)
  );
}, []);

const maxOfAll = Math.max(0, ...maxArray.map(e => e.dst));

const filteredMaxArray = maxArray.filter(
  e => e.dst === maxOfAll
).map(e => ({x: e.x, y: e.y}));

console.log(filteredMaxArray);

person sergdenisov    schedule 04.09.2017
comment
Почему не этот Math.max(max, ...row) ? - person Hassan Imam; 04.09.2017
comment
@SergeyDenisov А как насчет дубликатов? - person As above so below; 04.09.2017
comment
@TudorApostol проверьте, пожалуйста, теперь все дубликаты сохранены. - person sergdenisov; 04.09.2017
comment
@SergeyDenisov Очень приятно, ценю старания. - person As above so below; 05.09.2017

Вы можете использовать одну функцию только с одним циклом по внешнему массиву и внутреннему массиву с хэш-таблицей для временных максимальных координат и с массивом сбора для результата.

function getMax(data) {
    return data.reduce(function (r, a, x) {
        var hash = Object.create(null),
            max = 0;

        a.forEach(function (o, y) {
            if (max <= o.dst) {
                max = o.dst;
                hash[max] = hash[max] || [];
                hash[max].push({ x, y });
            }
        });
        return r.concat(hash[max]);
    }, []);
}

var data = [[{ dst: 1 }, { dst: 2 }, { dst: 3 }], [{ dst: 4 }, { dst: 5 }, { dst: 6 }], [{ dst: 7 }, { dst: 8 }, { dst: 9 }]]

console.log(getMax(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }

person Nina Scholz    schedule 04.09.2017