Nick Huemmer

22 September 2022

Identical Row and Column?

Identical Row and Column?

This was an interesting one and really provided a chance to test nested loops and ways to compare arrays.

My solution is rather long and verbose compared to the top solutions. But it was a great learning opportunity exercise in looping!

The challenge:

Write a function that returns true if there exists a row that is identical to a column in a 2-D matrix, otherwise false.

To illustrate:

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

// 2nd row + 2nd column are identical: [2, 4, 9, 8]

Examples

hasIdentical([ [4, 4, 4, 4], [2, 4, 9, 8], [5, 4, 7, 7], [6, 4, 1, 0] ]) ➞ true

hasIdentical([ [4, 4, 9, 4], [2, 1, 9, 8], [5, 4, 7, 7], [6, 4, 1, 0] ]) ➞ false

hasIdentical([ [4, 4] [2, 1] ]) ➞ false

hasIdentical([ [4, 2] [2, 1] ]) ➞ true

My Solution

function hasIdentical(arr) {
	//check to make sure it's a 2D array
  function checker(arr) {
    let checks = []
    const avgs = arr.map(x=> checks.push(x.length))
    return checks.reduce((a,c)=> a + c )/arr.length === arr.length
  }
	if (!checker(arr)) return false
  // tArr is the flattened, transposed array gotten from the double loop iterating over each array
  let tArr = []
  for (let i=0; i<arr.length; i++) {
    for (let j=0; j<arr[0].length; j++) {
      tArr.push(arr[j][i])
    }
  }
  // sArr is the tArr array split into the same lengths as the arrays in arr.
  let sArr = []
  for (let k=0; k<tArr.length; k+=arr.length) {
    sArr.push(tArr.slice(k, k+arr.length))
  }
  //compareArrays takes two arrays and compares them to see if they are equal.
  const compareArrays = (a, b) => 
    a.length === b.length &&
    a.every((val, index) => val === b[index]);
  //initiate array to hold tests from compareArrays of arr and sArr arrays
	let tests = []
  // nested loop that allows each array to be tested against each other.
	for (let i=0; i<arr.length; i++) {
    for (let j=0; j<arr[0].length; j++) {
	tests.push(compareArrays(arr[i], sArr[j]))
    }
	}
  //if any results are true from the nested loop and compareArrays, then return true.
	return tests.some(x=> x)
}

hasIdentical([
  [4, 4, 4, 4],
  [2, 4, 9, 8],
  [5, 4, 7, 7],
  [6, 4, 1, 0]
]) // true

hasIdentical([
  [4, 4, 9, 4],
  [2, 1, 9, 8],
  [5, 4, 7, 7],
  [6, 4, 1, 0]
]) // false


hasIdentical([
  [4, 4],
  [2, 1]
]) //➞ false

hasIdentical([
	[4, 2, 4, 6, 1], 
	[2, 4, 9, 4, 5], 
	[5, 1, 7, 1, 9], 
	[6, 4, 1, 0, 33], 
	[5, 5, 5, 33, 5]
]) // true

hasIdentical([
	[4, 4, 4],
	[2, 1, 4]
]) // false

hasIdentical([
	[4, 4, 4]
]) // false

Other solutions:

This solution uses the JSON.stringify method in separate row and column functions to parse out the elements in the rows and columns of the matrix. The elements are then compared against each other. Notice how complexity is eliminated by converting the arrays from the columns and rows to strings.

function hasIdentical(arr) {
	const row = r => JSON.stringify(arr[r]);
	const col = c => JSON.stringify(arr.map(r => r[c]));
	for (let r in arr) {
		for (let c in arr) {
			if (row(r) === col(c)) { return true; }
		}
	}
	return false;
}
//mbbentley

This solution is similar to the above, but it uses Object.keys to solve it.

const hasIdentical = arr => {
	const reversedArr = Object.keys(arr[0]).map(c => arr.map(r =>r[c]));
	return arr.some(r => reversedArr.some(c => String(c) === String(r)));
}
//Alessandro Manicone

Here, a function called getColumn is defined and used to make an array using Array.from to pass in and get strings of the values in the matrix columns. The strings from the rows are then compared with the strings from the columns.

const getColumn = (arr, x) =>
  Array.from({ length: arr.length }, (_, y) => arr[y][x]);

const hasIdentical = arr => {
  const rows = arr.map(JSON.stringify);
  const cols = Array.from({ length: arr.length }, (_, x) =>
    JSON.stringify(getColumn(arr, x))
  );

  return cols.some(col => rows.includes(col));
};
//Pustur