我正在使用的是一个对象矩阵,我试图找到每个对象的最大值,包括重复。
这是我迄今为止所拥有的:
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]。
答案 0 :(得分:2)
使用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);
答案 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; }