Javascript:将2D数组拆分为方形区域,并将每个区域的最大值相加

时间:2018-03-14 18:47:02

标签: javascript arrays

我想从左上角开始将矩阵分割成具有给定尺寸(k)的正方形区域,然后将每个区域的最大值相加。 这是我到目前为止所做的。



arr = [
  [ 0, 8, 1, 1, 10, 6 ],
  [ 6, 8, 7, 0, 3, 9],
  [ 0, 7, 6, 8, 6, 5],
  [ 4, 0, 2, 7, 2, 0],
  [ 4, 4, 5, 7, 5, 1]
], l = console.log, j = JSON.stringify

result = [0, 3].map(i => arr.map(a => a.slice(i, i+3)))  // map over the indexes to split by to get the parts

l(j(result ))




我不是javascript的专家,但我想学习。 任何帮助将不胜感激。

6 个答案:

答案 0 :(得分:1)

我知道它有点复杂,但它正在发挥作用。它将尝试获得你想要的区域,但如果不可能有特定大小的区域,它将采取任何剩余。(在我们的例子中,它将在3 * 3的2个区域中划分数组,并且另外2个区域为2 * 3)(警告: - 如果区域中的所有元素都小于-100,它将无法工作,如果您希望它工作,请相应地更改'runningMax'的值)

function max(arr){
  var runningMax=-100;
	for(i = 0, i2 = arr.length; i<i2; i++) {
      runningMax = Math.max.apply(null, arr[i].concat(runningMax));
  }
  return runningMax;
}

arr = [
  [ 0, 8, 1, 1, 10, 6 ],
  [ 6, 8, 7, 0, 3, 9],
  [ 0, 7, 6, 8, 6, 5],
  [ 4, 0, 2, 7, 2, 0],
  [ 4, 4, 5, 7, 5, 1]
], l = console.log, j = JSON.stringify

result = [0, 3].map(i => arr.map(a => a.slice(i, i+3)));

y=[0,3].map(i=>result.map(a=>a.slice(i,i+3)));

var v=0;
y.forEach(function(e){
	e.forEach(function(q){
		//console.log(max(q) + "  "+ q);
		v+=max(q);
	})
});

console.log(v);

答案 1 :(得分:0)

    
const arr = [
  [ 0, 8, 1, 1, 10, 6 ],
  [ 6, 8, 7, 0, 3, 9],
  [ 0, 7, 6, 8, 6, 5],
  [ 4, 0, 2, 7, 2, 0],
  [ 4, 4, 5, 7, 5, 1]
];

const sizeX = 3, sizeY = 3;

// Go over the different squares
for(let minX = 0; minX < arr.length - sizeX; minX++){
  for(let minY = 0; minY < arr[0].length - sizeY; minY++){
     // Sum their content up
     var sum = 0;
     for(let x = minX; x < minX + sizeX; x++)
        for(let y = minY; y < minY + sizeY;  y++)
            sum += arr[x][y];
      // Do whatever with the sum
      console.log(sum)
   }
}

答案 2 :(得分:0)

您可以使用reduce()forEach()方法

在区域中拆分矩阵

const arr = [
    [0, 8, 1, 1, 10, 6],
    [6, 8, 7, 0, 3, 9],
    [0, 7, 6, 8, 6, 5],
    [4, 0, 2, 7, 2, 0],
    [4, 4, 5, 7, 5, 1]
  ], l = console.log, j = JSON.stringify

function splitMatrix(data, n) {
  let row = 0;
  return data.reduce(function(r, a, i) {
    if (i && i % n == 0) row++;
    let col = 0;
    a.forEach(function(e, j) {
      if (j && j % n == 0) col++;
      if (!r[row]) r[row] = [];
      if (!r[row][col]) r[row][col] = [];
      r[row][col].push(e)
    })
    return r;
  }, [])
}

const s = splitMatrix(arr, 3);
console.log(j(s))

要获得每个区域的最大值,您可以在foreach循环中执行此操作,然后使用reduce()对这些值求和。

const arr = [
    [0, 8, 1, 1, 10, 6],
    [6, 8, 7, 0, 3, 9],
    [0, 7, 6, 8, 6, 5],
    [4, 0, 2, 7, 2, 0],
    [4, 4, 5, 7, 5, 1]
  ], l = console.log, j = JSON.stringify

function splitMatrix(data, n) {
  let row = 0;
  return data.reduce(function(r, a, i) {
    if (i && i % n == 0) row++;
    let col = 0;
    a.forEach(function(e, j) {
      if (j && j % n == 0) col++;
      if (!r[row]) r[row] = [];
      if (!r[row][col]) r[row][col] = [e];
      if (r[row][col][0] < e) r[row][col][0] = e;
    })
    return r;
  }, [])
}

const max = splitMatrix(arr, 3)
const result = [].concat(...max).reduce((r, [e]) => r + e, 0);
console.log(j(max))
console.log(result)

答案 3 :(得分:0)

在您的示例中,阵列为6x5,因此您无法将其均匀分割为方形区域。除了这一点之外,这还有一点点。如果你想要完成整个过程,那么第一步就是拥有一个可以占用矩阵特定块的函数并总结它。

我们假设我们有一个矩阵,我们想制作一个x,y,宽度和高度的函数,用于我们想要总结的内容。

&#13;
&#13;
const m = [
 [1,2,3,4,5],
 [2,3,4,5,6],
 [3,4,5,6,7],
 [8,9,10,11,12]
];

const sumArea = (m, x, y, w, h) => {
  let sum = 0;
  
  if (y + h > m.length) {
    throw new Error('Matrix is not tall enough for the requested area');
  }
  
  if (x + w > m[0].length) {
    throw new Error('Matrix is not wide enough for the request area');
  }
  
  for (let j = y; j < y + h; j++) {
    for (let i = x; i < x + w; i++) {
      sum += m[j][i];
    }
  }
  
  return sum;
}

console.log(sumArea(m, 0, 0, 3, 3));
&#13;
&#13;
&#13;

有了这个,我们可以循环遍历矩阵的任意区域并总结其中的所有内容。为此,我们只使用从起点(forx)到结尾(yx + width)的y + height循环。

我添加了一个检查区域是否超出范围并抛出错误。您也可以将它们计为零并跳过它们(通过在for循环中添加一些条件。

在那之后,为了解决所有这些问题,你只需迭代每一位。

&#13;
&#13;
const m = [
 [1,2,3,4],
 [2,3,4,5],
 [3,4,5,6],
 [8,9,10,11]
];

const sumArea = (m, x, y, w, h) => {
  let sum = 0;
  
  if (y + h > m.length) {
    throw new Error('Matrix is not tall enough for the requested area');
  }
  
  if (x + w > m[0].length) {
    throw new Error('Matrix is not wide enough for the request area');
  }
  
  for (let j = y; j < y + h; j++) {
    for (let i = x; i < x + w; i++) {
      sum += m[j][i];
    }
  }
  
  return sum;
}

const sumSquares = (m, w, h) => {
  let result = [];
  
  for (let y = 0; y < m.length / h; y++) {
    result[y] = [];
    
    for (let x = 0; x < m[0].length / w; x++) {
      result[y][x] = sumArea(m, x * w, y * h, w, h);
    }
  }
  
  return result;
}

console.log(sumSquares(m, 2, 2));
&#13;
&#13;
&#13;

为此,我们遍历我们将拥有的每个方格。我们所拥有的正方形的数量是矩阵的大小除以正方形的宽度(因此,矩阵为4x4,2x2正方形将具有2个横向和2个向下)。然后我把它们放到另一个矩阵中以显示它们的总大小。

答案 4 :(得分:0)

使用相同的长度和高度数组,您可以迭代数组并获取组的索引进行计数。

&#13;
&#13;
var array = [[0, 8, 1, 1, 10, 6], [6, 8, 7, 0, 3, 9], [0, 7, 6, 8, 6, 5], [4, 0, 2, 7, 2, 0], [4, 4, 5, 7, 5, 1], [0, 1, 0, 1, 0, 1]],
    result = array.reduce((r, a, i) => {
        a.forEach((b, j) => {
            r[Math.floor(i / 3)] = r[Math.floor(i / 3)] || [];
            r[Math.floor(i / 3)][Math.floor(j / 3)] = (r[Math.floor(i / 3)][Math.floor(j / 3)] || 0) + b;
        });
        return r;
    }, []);

console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 5 :(得分:0)

根据我的理解,您想要查看给定矩阵的所有可能的3x3子矩阵。所以我假设您要在示例矩阵中查看:

[ 0, 8, 1 ]    [ 8, 1, 1 ]    [ 1, 1, 10]    [ 1, 10, 6 ]
[ 6, 8, 7 ]    [ 8, 7, 0 ]    [ 7, 0, 3 ]    [ 0, 3,  9 ]
[ 0, 7, 6 ]    [ 7, 6, 8 ]    [ 6, 8, 6 ]    [ 8, 6,  5 ]

[ 6, 8, 7 ]    [ 8, 7, 0 ]    [ 7, 0, 3 ]    [ 0, 3, 9 ]
[ 0, 7, 6 ]    [ 7, 6, 8 ]    [ 6, 8, 6 ]    [ 8, 6, 5 ]
[ 4, 0, 2 ]    [ 0, 2, 7 ]    [ 2, 7, 2 ]    [ 7, 2, 0 ]

[ 0, 7, 6 ]    [ 7, 6, 8 ]    [ 6, 8, 6 ]    [ 8, 6, 5]
[ 4, 0, 2 ]    [ 0, 2, 7 ]    [ 2, 7, 2 ]    [ 7, 2, 0]
[ 4, 4, 5 ]    [ 4, 5, 7 ]    [ 5, 7, 5 ]    [ 7, 5, 1]

然后我理解你想要找到最大值(12个矩阵的12个最大值):

8    8   10   10

8    8    8    9

7    8    8    8

这些的总和是100.所以,如果这确实是你想要的结果,这是获得它的功能性方法:

&#13;
&#13;
const arr = [
  [ 0, 8, 1, 1, 10, 6 ],
  [ 6, 8, 7, 0, 3, 9],
  [ 0, 7, 6, 8, 6, 5],
  [ 4, 0, 2, 7, 2, 0],
  [ 4, 4, 5, 7, 5, 1]
];

const sum = arr.slice(2).reduce( 
    (sum, row, i) => row.slice(2).reduce( 
        (sum, a, j) => sum + Math.max(...arr[i].slice(j,j+3), 
                                      ...arr[i+1].slice(j,j+3), 
                                      ...row.slice(j,j+3)),
        sum
    ), 0
)

console.log(sum);
&#13;
&#13;
&#13;