如果所有值都相等,则从2d矩阵中删除cols和rows

时间:2017-11-10 19:59:49

标签: javascript arrays object matrix

  1. 我的矩阵/ 2d数组看起来像这样。 * | *
  2. 我想得到这个结果

           |                                |
           Y                                Y
    
    [                                 
       [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 A A A A      --> remove col 1
    2 B B B B
    3 B X B C
    4 A B O B
    
    
    
    0 1 2 3 4
    1 A A C A      
    2 B B C B
    3 B X C C
    4 A B C B
          |
          |
          Y
      remove row 3
    
  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)
      }
    }

5 个答案:

答案 0 :(得分:0)

从技术上讲,您在第二对循环中检查。我很确定这应该如何编写。

dummysort

答案 1 :(得分:0)

独立删除行和列:

删除列和行,同时使用原始未更改的矩阵作为参考:

&#13;
&#13;
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"));
&#13;
&#13;
&#13;

依赖删除行和列

根据删除行或列的顺序,可能会得到不同的结果:

&#13;
&#13;
/* 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"));
&#13;
&#13;
&#13;

备注:

  1. 要检查某行是否有不同的值,我使用some检查行中是否有其他值与行中的第一个元素不同。
  2. 要检查列i是否具有相同的值,我使用every检查每行的i-th元素是否等于i-th元素第一行。

答案 2 :(得分:0)

您可以使用Array#filter将行转换为Set。如果集合的大小为1,则应删除该数组。

要过滤列,从头开始重建网格会更容易。用Array#reduce迭代第一行。累加器使用Array#from初始化新网格。对于每一列,从原始列创建一个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);

答案 3 :(得分:0)

试试这个:(第一行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/

答案 4 :(得分:0)

我以递归方式实现了这一点,它重复地通过uniqueifier运行结果数组,直到没有进行任何修改。

使X方向行明显比列更直接,因此您可以通过旋转矩阵来处理不同的列 - &gt;不同的X方向 - &gt;向后旋转。

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

Fiddle稍微容易阅读控制台输出。

很棒的问题 - 有趣的谜题!