[英]Remove cols and rows from 2d matrix if all their values are equal
我想得到这个结果
| | YY [ [0,0,0,0], [ [0,1,0,2], ---> [1,0,2], [0,2,3,0], [2,3,0], [0,5,0,0] [5,0,0] ] [
我想删除所有行/列,如果它们的值都相等。
0 1 2 3 4 1 AAAA --> remove col 1 2 BBBB 3 BXBC 4 ABOB 0 1 2 3 4 1 AACA 2 BBCB 3 BXCC 4 ABCB | | Y remove row 3
我的想法是使用一个可以在下面找到的函数,但是我的代码似乎不起作用。
检查X方向的“ 相等性 ”是没有问题的,但是我不知道Y方向有什么问题。 显然,它不能很好地工作:p
我的功能:
var myarray=[ [0,0,0,0], [1,0,0,0], [1,0,0,0], [1,0,0,0] ] remove_equal_rows(myarray) function remove_equal_rows(array) { /* x direction --> (working) */ var statusX=true; for (var i=0; i<array.length;i++) { for (var j = 1; j < array[i].length; j++) { if (array[i][j] !== array[i][0]) { statusX=false;break; } else statusX=true } console.log('remove col "'+i+'": ' + statusX) } console.log('-------') /* y direction --> (not working) */ var statusY=true; for (var i=0;i<array[0].length;i++) { for (var j = 1; j < array[i].length; j++) { if (array[j][i] !== array[j][0]) { statusY=false;break; } else statusY=true } console.log('remove row "'+i+'": ' + statusY) } }
从技术上讲,您是在第二对循环中再次检查行。 我很确定这是应该如何编写的。
var statusY=true;
for (var i=0;i<array[0].length;i++) {
for (var j = 1; j < array.length; j++) {
if (array[j][i] !== array[0][i]) {
statusY=false;break;
} else statusY=true
}
console.log('remove row "'+i+'": ' + statusY)
}
独立删除行和列:
使用原始的未更改矩阵作为参考时,删除列和行:
function remove(matrix) { let newMatrix = matrix.filter(row => row.some(e => e != row[0])) // filter the rows that have different values .map(row => row.slice(0)); // copy them into newMatrix (so the original matrix isn't affected by altering them (the rows)) if(newMatrix.length === 0) return newMatrix; // if newMatrix turned out to be rowless (then just retrun it without attempting to clean the columns) for(var i = newMatrix[0].length - 1; i >= 0; i--) { // for each column (looping backwards so that removing column won't affect the index i) var first = matrix[0][i]; // getting the value of the i-th column of the first row if(matrix.every(row => row[i] === first)) { // if all rows have the same value as first for the i-th column newMatrix.forEach(row => row.splice(i, 1)); // then remove the i-th item (column) from each row } } return newMatrix; } var result = remove([ [0,0,0,0], [1,0,0,0], [1,0,5,0], [1,0,0,0] ]); console.log(result.join("\\n"));
依赖删除行和列 :
根据删除行或列的顺序,可能会得到不同的结果:
/* Same code as before except that we now have different functions: * removeRows: that take a matrix and remove rows that have the same values * removeColumns: that take a matrix and remove columns that have the same values * depending on wether to call removeRows or removeColumns, you may get different results as shown in an example bellow. (You my call removeRows then removeColumns then call removeRows again and get a different result et cetera...) */ function removeRows(matrix) { return matrix.filter(row => row.some(e => e != row[0])); } function removeColumns(matrix) { if (matrix.length === 0) return matrix; for (var i = matrix[0].length - 1; i >= 0; i--) { var first = matrix[0][i]; if (matrix.every(row => row[i] === first)) { matrix.forEach(row => row.splice(i, 1)); } } return matrix; } console.log("Removeing rows then columns:"); var result = removeRows([ [0, 0, 0, 0], [1, 0, 0, 0], [1, 0, 5, 0], [1, 0, 0, 0] ]); result = removeColumns(result); console.log(result.join("\\n")); console.log("Removeing columns then rows:"); var result = removeColumns([ [0, 0, 0, 0], [1, 0, 0, 0], [1, 0, 5, 0], [1, 0, 0, 0] ]); result = removeRows(result); console.log(result.join("\\n"));
笔记:
some
来检查该行中是否存在与该行的第一个元素不同的其他值。 i
是否具有相同的值,我使用every
来检查每行i-th
元素是否等于第一行的第i-th
元素。 您可以通过使用Array#filter并将行转换为Set来进行行操作 。 如果集合的大小为1,则应删除该数组。
要过滤列,从头开始重建网格更容易。 使用Array#reduce迭代第一行。 作为累加器,使用Array#from初始化一个新的网格。 对于每个列,请从原始列创建一个Set(在过滤行之前),如果set的大小大于0,请使用Array#forEach将其项推到新网格中。
const myarray = [ [0,0,0,0], [1,0,0,0], [1,0,0,0], [1,0,0,0] ]; const filteredRows = myarray.filter((arr) => new Set(arr).size !== 1); // if a the set of the row contains only 1 item it should be remove const filteredColumns = (filteredRows[0] || []).reduce((r, _, i) => { // iterate the 1st row const keep = new Set(myarray.map((arr) => arr[i])).size > 1; // if a the set of the column in the original grid contains more than 1 item, it should be kept keep && filteredRows.forEach((arr, j) => r[j].push(arr[i])); // if we keep it, and the column to the grid return r; }, Array.from({ length: filteredRows.length }, () => [])); // initialize with an empty grid console.log(filteredColumns);
试试这个:(第一行0将被删除,然后col0和col 2将被删除)
var myarray=[
[0,0,0,0],
[1,0,2,0],
[1,1,2,1],
[1,0,2,0]
]
remove_equal_rows(myarray)
function remove_equal_rows(myArray) {
/*
x direction --> (working)
*/
var resultX = [];
for (var i=0; i<myArray.length;i++) {
statusX = true;
for (var j = 1; j < myArray[i].length; j++) {
if (myArray[i][j] !== myArray[i][0]) {
statusX=false;break;
}
}
if (statusX) { resultX.push(i); }
}
console.log('rows indexes to remove : ', resultX);
resultX.map(function(item) { myArray.splice(item,1); });
console.log('-------', myArray);
/*
y direction --> (now working)
*/
var statusY, resultY = [];
for (var i=0;i<myArray.length;i++) {
statusY = true;
for (var j = 1; j < myArray.length; j++) {
console.log(j, i, myArray[j][i]);
if (myArray[j][i] !== myArray[0][i]) {
statusY=false;break;
}
}
if (statusY) {resultY.push(i);}
}
console.log('cols indexes to remove : ', resultY);
resultY.map(function(item) { myArray.splice(item,1); });
console.log('-------', myArray);
}
查看这个小提琴: https : //jsfiddle.net/a9qvtuu4/
我以递归方式实现了该过程,在该过程中,它反复通过唯一符运行结果数组,直到不进行任何修改为止。
使X方向的行与众不同比比列更直接,因此可以通过旋转矩阵-> X方向不同->向后旋转来处理不同的列。
var masterArr = [ [0,0,0,0], [1,0,0,0], [1,0,3,0], [1,0,0,4] ]; function uniqueColRow(arr) { if(arr.length === 0 || arr[0].length === 0) { return arr; } var distinctRows = arr.filter((x) => { return x.filter(unique).length > 1; }); var flip = rotateArr(distinctRows); var distinctCols = flip.filter((x) => { return x.filter(unique).length > 1; }); var resultArr = rotateArr(distinctCols); if(arr.length !== resultArr.length || arr[0].length !== resultArr[0].length) { console.log('running again with:'); console.log(resultArr); return uniqueColRow(resultArr); }else { return resultArr; } } console.log('Original:'); console.log(masterArr); console.log('\\n'); var result = uniqueColRow(masterArr); console.log('\\nFinal:') console.log(result); function rotateArr(arr) { return arr[0].map((col, i) => arr.map(row => row[i])); } function unique(item, i, self) { return self.indexOf(item) === i; }
小提琴的控制台输出略显易读。
好问题-有趣的难题!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.