在矩阵中查找重复的最大值

Finding duplicate max values in a matrix

我正在处理的是一个对象矩阵,我试图找到每个对象的最大值,包括重复对象。

这是我到目前为止所拥有的:

        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].

使用 Array.prototype.reduce(), arrow function expression, Math.max(), spread operator, Array.prototype.map(), Array.prototype.concat(), Array.prototype.filter() 查看一些魔术:

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);

您可以使用一个函数,只在外部数组和内部数组上循环一次,并使用散列 table 作为临时最大坐标,并使用一个收集数组作为结果。

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; }