1

I need help updating a matrix array. It starts with set values and i need to pass in coordinates to update the values.

I have a set base matrix:

var myMatrix = [
    ['-','-','-','-','-','-','-','-','-','-'],
    ['-','-','-','-','-','-','-','-','-','-'],
    ['-','-','-','-','-','-','-','-','-','-'],
    ['-','-','-','-','-','-','-','-','-','-'],
    ['-','-','-','-','-','-','-','-','-','-'],
    ['-','-','-','-','-','-','-','-','-','-'],
    ['-','-','-','-','-','-','-','-','-','-'],
    ['-','-','-','-','-','-','-','-','-','-'],
    ['-','-','-','-','-','-','-','-','-','-'],
    ['-','-','-','-','-','-','-','-','-','-']
];

I was able to update specific points in the matrix to read like so:

----x-----
-----x----
--------x-
--------x-
---x------
----------
-------x--
----------
----x-----
-------x--

with this function:

function stepTwo(coordinates) {
    console.log('Step Two');
    for(var j =0; j < coordinates.length; j ++) {
        myMatrix[coordinates[j].y][coordinates[j].x] = 'x';
    }
    for(var i = 0; i < myMatrix.length; i++) {
        console.log(myMatrix[i].join(' '));
    }
}

var coordinatesArray = [
    {x: 4, y: 0},
    {x: 5, y: 1},
    {x: 8, y: 2},
    {x: 8, y: 3},
    {x: 3, y: 4},
    {x: 7, y: 6},
    {x: 4, y: 8},
    {x: 7, y: 9},
];

stepTwo(coordinatesArray);

Now I want to make another function that does something similar, it should take in value to update the matrix like so:

xxxxx-----
xxxxxx----
xxxxxxxxx-
xxxxxxxxx-
xxxx------
----------
xxxxxxxx--
----------
xxxxx-----
xxxxxxxx--

Basically pass in the row and how many '-'s to convert to 'x's.

JS Fiddle of my current work (stepThree is where I need help): https://jsfiddle.net/2vbd27f0/73/

Thanks in advanced for the help!

Matt Lewis
  • 53
  • 3
  • hint: use `Array.prototype.some` or `Array.prototype.map`. which this functions it's very easy. look at your fiddle: https://jsfiddle.net/2vbd27f0/74/ – Joshua K Aug 13 '15 at 13:02
  • Just notice ... stepTwo isn't updating the array. You will have to return the result. Arrays are not passed by reference. – Emmanuel Delay Aug 13 '15 at 13:09
  • @EmmanuelDelay [First Google result](http://orizens.com/wp/topics/javascript-arrays-passing-by-reference-or-by-value/). Also he's not even passing the array anywhere. It's defined in a global scope and the function is accessing the exact same variable (in scope). – Shadowen Aug 13 '15 at 13:19

2 Answers2

0

Short solution

I assume you want to go to row points[j].y and create points[j].x x's.

for(var j = 0; j < points.length; j++) {
    for(var k = 0; k < points[j].x; k++) {
        myMatrix[points[j].y][k] = 'x';
    }
}

How it works

The outer for loop iterates through the points. Using j as the counter, points[j] is the current point. points[j].y is the current row number.

For this row, we want to create point[j].x x's. So there is an inner for loop that runs from 0 to point[j].x, using the variable k as its counter.

Then in each cell we have selected with the coordinate (j, k), we set the value to x.

Clearer solution

With all this in mind, we can make the above solution easier to understand.

for(var pointNumber = 0; pointNumber < points.length; pointNumber++) {
    // Pick one point
    var currentPoint = points[pointNumber];

    // We want to set the points (0, row) .. (currentPoint.x, row), so we use another loop.
    var row = currentPoint.y;
    // Set all the columns to 'x'
    for(var column = 0; column < currentPoint.x; column++) {
        myMatrix[row][column] = 'x';
    }
}
Shadowen
  • 838
  • 5
  • 14
  • you can optimize your for loops or better: use `forEach`. – Joshua K Aug 13 '15 at 13:10
  • @Shadowen that did exactly what I needed it to, thanks! – Matt Lewis Aug 13 '15 at 13:12
  • @JoshuaK [`forEach` is less efficient than `for`](http://jsperf.com/for-vs-foreach/37). Anyways, the point isn't to optimize; it's to learn. If you wanted to optimize you would remove all duplicate rows from `points` first of all... – Shadowen Aug 13 '15 at 13:16
  • @Shadowen optimize was the wrong word. I ment improve. forEach is a better coding style than using for (if you want to iterate over arrays). It's clear what are you doing in the first moment you see the code. for(...) you have to "analyze" the expression. the speed... yeah. that is bad sometimes, but in this case we have no high performance application. and IF you use for instead of foreach, than use `for(var i=0,pointNumber=points.length;i – Joshua K Aug 13 '15 at 13:29
  • 1
    @JoshuaK This point has been debated many times already. [Please](http://stackoverflow.com/questions/6261953/) [read](http://stackoverflow.com/questions/6973942/) [these](http://stackoverflow.com/questions/9329446/) [threads](http://stackoverflow.com/questions/12796887/). It is usually easiest (style-wise) to use a simple `for` loop. Again, I have to point you to JSPerf. If you are using a modern browser (Chrome, IE9, etc.) I believe `for` is actually faster than `for cached`. – Shadowen Aug 13 '15 at 13:52
  • @Shadowen oh wow. thank you. Never noticed that, that it is this way in javascript. (Win7, FF40.0 it is perfectly even btw. the difference (run the test 10 times)) was at most 5 loops. again: thank you. I never proved it by myself in javascript. Thought it is the same like in other languages. – Joshua K Aug 13 '15 at 14:00
0

This is my take on the question - create a new array of x's by the needed number, and concat the sliced leftovers (fiddle):

function stepThree(points) {
    points.forEach(function(entry) {
        var row = myMatrix[entry.y];

        if(!row) { // if no row continue to next iteration
            return;
        }

        var fillNum = entry.x > row.length ? row.length : entry.x; // if the number to fill is higher than length use length

        myMatrix[entry.y] = new Array(fillNum + 1) // create an array which is bigger by 1 from places to fill
            .join('x') // join it using x's getting the right number
            .split('') // split it to create new array
            .concat(row.slice(fillNum)); // add the leftovers
    });
}
Ori Drori
  • 183,571
  • 29
  • 224
  • 209