1
function findMin(array) {
  return Math.min.apply(Math, array);
}

function rearrange(matrix) {
  let min = 0;
  let newMatrix = [];

  for (let i = 0; i < matrix.length; i++) {
    let min = findMin(matrix[i]);
    newMatrix[i].push(min);   
  }  

  return newMatrix;

}

Example input:

let matrix = [[2,7,1], 
             [0,2,0], 
             [1,3,1]]

rearrange(matrix);

Log:

Uncaught TypeError: Cannot read property 'push' of undefined
    at reArrange (test.js:11)
    at test.js:23

I'm trying to have the nested arrays sorted in an increasing order. If I didn't get it wrong, it doesn't happen because newMatrix[i] is not defined. But can't JS just create it and push the element? Do we need an extra step prior to doing this? Could you please suggest me another way, if this method won't work?

4
  • 2
    newMatrix[i] isn't an array. newMatrix[i] = []; newMatrix[i].push should work. (untested) Commented Aug 12, 2017 at 11:20
  • As youre using let, ypu might use the spread operator instead of this afwul .apply ... Commented Aug 12, 2017 at 11:20
  • 1
    newMatrix is your array. You are trying to push in the ith element of your array, which is undefined Commented Aug 12, 2017 at 11:21
  • why do you need an extra array for the result? Commented Aug 12, 2017 at 11:24

4 Answers 4

1

That's because you don't initialize the second dimension in your output Array. In JavaScript, if you haven't explicitly assigned to a certain element of an array, it evaluates to undefined, which obviously is neither an Array, nor an array like object and does not have a push() method.

The quickest solution to your problem should be declaring the inner arrays as well.

  let newMatrix = [[], [], []];

A better, generic way would be to append an empty array to newMatrix every time you encounter a row that does not exist.


I also suspect that you algorithm is incorrect. Could you specify what exactly you intend to achieve by 'rearranging' the array? Because all your current code does is populate newMatrix with the minimum of each row. You're going to end up with [[1], [0], [1]] with the current fix. Is that intentional? Check your logic.

EDIT: Apparently, you're trying to rearrange the maxtix in such a way that the result contains each row in sorted order. Here's how to do that:

function rearrange(matrix) {
  let min = 0;
  let newMatrix = [];

  for (let i = 0; i < matrix.length; i++) {
    let sortedRow = matrix[i].sort((a, b) => a > b)
    newMatrix.push(sortedRow);
  }

  return newMatrix;
}

console.log(rearrange([
  [7, 6, 8],
  [1, 9, 9],
  [8, 5, 1]
]))

Sign up to request clarification or add additional context in comments.

5 Comments

Actually it wasn't the intention. I'm trying to rearrange the rows in a way that the elements would have an increasing order. I thought I could accomplish that by moving the minimum elements to a new array by pushing from the old one, and after then I would remove it from the old array before getting the minimum again (didn't implement this part yet).
That's what I suspected. What you need to do is sort the array on each iteration, and push that into your new array. Will update my answer in a couple of minutes.
Exactly what I needed, and seems like I didn't have to use the previous logic at all. Thank you!
I suspect what you originally intended to do was to repeatedly find the minimum element in the original row, and populate the new row with it. This is a slow operation, because you end up doing a quadratic number of operations. You should look into basic complexity theory, as well as the basic sorting / searching algorithms. That should give you a good handle on why sorting each row before insertion is a faster operation than repeatedly computing the minimum.
You guessed it right. I just began learning JS and overall don't really have a long background in programming. Will definitely check out the concepts you suggested, appreciate it!
1

You need to make shure that matrix[i] is an array:

 (newMatrix[i] || (newMatrix[i] = [])).push(min);

Or you set it to an array directly:

 newMatrix[i] = [min];

Comments

1

You need to assign a new array before using Array#push

newMatrix[i] = [];

function findMin(array) {
    return Math.min.apply(Math, array);
}

function rearrange(matrix) {
    let min = 0;
    let newMatrix = [];

    for (let i = 0; i < matrix.length; i++) {
        let min = findMin(matrix[i]);
        newMatrix.push(min);
    }
    return newMatrix;
}

let matrix = [[2, 7, 1], [0, 2, 0], [1, 3, 1]];

console.log(rearrange(matrix));
.as-console-wrapper { max-height: 100% !important; top: 0; }

As an alternative solution, you could just map the result of findMin.

function findMin(array) {
    return Math.min.apply(Math, array);
}

function rearrange(matrix) {
    return matrix.map(findMin);
}

let matrix = [[2, 7, 1], [0, 2, 0], [1, 3, 1]];

console.log(rearrange(matrix));

Comments

1

Your code is not working because you miss to initialize the array before to push the min. In your case you have newMatrix which is an empty array. But you expect than that the array should have arrays inside: So before this line:

newMatrix[i].push(min);

You could do:

newMatrix[i] = [];

But in this way what you are going to achieve is a new array with arrays, and each array inside has just the min of the input arrays. If you want a new array ordered inside, you could do that in this way:

var result = [[5,3,1], [4,5,1]].reduce(function(a, b) {
  a.push(b.sort());
  return a;
}, []);
console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.