在矩阵

时间:2017-09-04 16:16:38

标签: javascript arrays algorithm array-algorithms

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

这是我迄今为止所拥有的:

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

并且在此函数中,在找到max之后,我将每列的每一行与最大值进行比较,并在符合条件的情况下将对象坐标推送到数组中。

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

2 个答案:

答案 0 :(得分:2)

使用Array.prototype.reduce()arrow function expressionMath.max()spread operatorArray.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);

答案 1 :(得分:0)

您可以使用单个函数,在外部数组和内部数组上只有一个循环,其中包含用于临时最大坐标的哈希表,以及用于结果的收集数组。

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