How do I traverse an array diagonally in javascript

14,702

Solution 1

From top left to bottom right

var array = ["ABCD","EFGH","IJKL"];

var Ylength = array.length;
var Xlength = array[0].length;
var maxLength = Math.max(Xlength, Ylength);
var temp;
for (var k = 0; k <= 2 * (maxLength - 1); ++k) {
    temp = [];
    for (var y = Ylength - 1; y >= 0; --y) {
        var x = k - y;
        if (x >= 0 && x < Xlength) {
            temp.push(array[y][x]);
        }
    }
    if(temp.length > 0) {
        document.body.innerHTML += temp.join('') + '<br>';
    }
}

(see also this Fiddle)


From the bottom left to top right

var array = ["ABCD","EFGH","IJKL"];

var Ylength = array.length;
var Xlength = array[0].length;
var maxLength = Math.max(Xlength, Ylength);
var temp;
for (var k = 0; k <= 2 * (maxLength - 1); ++k) {
    temp = [];
    for (var y = Ylength - 1; y >= 0; --y) {
        var x = k - (Ylength - y);
        if (x >= 0 && x < Xlength) {
            temp.push(array[y][x]);
        }
    }
    if(temp.length > 0) {
        document.body.innerHTML += temp.join('') + '<br>';
    }
}

(see also this Fiddle)


Combined

As there's but a single line of difference between both, you can easily combine them in a single function :

var array = ["ABCD","EFGH","IJKL"];

function diagonal(array, bottomToTop) {
    var Ylength = array.length;
    var Xlength = array[0].length;
    var maxLength = Math.max(Xlength, Ylength);
    var temp;
    var returnArray = [];
    for (var k = 0; k <= 2 * (maxLength - 1); ++k) {
        temp = [];
        for (var y = Ylength - 1; y >= 0; --y) {
            var x = k - (bottomToTop ? Ylength - y : y);
            if (x >= 0 && x < Xlength) {
                temp.push(array[y][x]);
            }
        }
        if(temp.length > 0) {
            returnArray.push(temp.join(''));
        }
    }
    return returnArray;
}

document.body.innerHTML = diagonal(array).join('<br>') +
                          '<br><br><br>' +
                          diagonal(array, true).join('<br>');

(see also this Fiddle)

Solution 2

This does the trick, and outputs the desired results to the screen:

var array = ['ABCD','EFGH','IJKL'];
var rows = array.length;
var cols = array[0].length;
for (var n = 0; n < cols + rows - 1; n += 1)
{
  var r = n;
  var c = 0;
  var str = '';
  while (r >= 0 && c < cols)
  {
    if (r < rows)
      str += array[r][c];
    r -= 1;
    c += 1;
  }
  document.write(str+"<br>");
}

Result:

A
EB
IFC
JGD
KH
L

Solution 3

Yet another solution:

function getAllDiagonal(array) {
    function row(offset) {
        var i = array.length, a = '';
        while (i--) {
            a += array[i][j + (offset ? offset - i : i)] || '';
        }
        return a;
    }

    var result = [[], []], j;
    for (j = 1 - array.length; j < array[0].length; j++) {
        result[0].push(row(0));
        result[1].push(row(array.length - 1));
    }
    return result;
}

var array = ['ABCD', 'EFGH', 'IJKL'];

document.write('<pre>' + JSON.stringify(getAllDiagonal(array), 0, 4) + '</pre>');

Solution 4

Try this

var TheArray = ['ABCD', 'EFGH', 'IJKL'];
    //amount of rows
    var RowLength = TheArray.length;
    //amount of colums
    var ColumnLength = TheArray[0].length;

    var totalNoComb = RowLength + ColumnLength - 1;
    var combArr = new Array(totalNoComb);
    for (var i = 0; i < totalNoComb; i++) {
        combArr[i] = "";
        for (var j = RowLength-1; j >-1; j--) {
            if (i - j > -1 && i - j < ColumnLength)
                combArr[i] += TheArray[j][i-j];
        }
    }
    alert(combArr);

    for (var i = 0; i < totalNoComb; i++) {
        combArr[i] = "";
        for (var j = 0; j < RowLength; j++) {
            if (i - j > -1 && i - j < ColumnLength)
                combArr[i] += TheArray[ RowLength -1-j][i - j];
        }
    }
    alert(combArr);

Solution 5

Use indices:

[i][j-i]

Where i goes from 0 to M-1

j goes from 0 to i

While j++ < N

for the matrix

type Array[M][N]

However this may miss a few at the bottom right if the matrix is rectangular, and you might need a second nested for loop with i and j to capture those.

Share:
14,702
viperia
Author by

viperia

Updated on June 03, 2022

Comments

  • viperia
    viperia almost 2 years

    I have an array with strings that I would like to traverse diagonally.
    Assumptions:

    • Each string is the same length.
    • Arrays could be square or rectangular, horizontally or vertically.

    The matrix looks like this:

    A B C D
    E F G H
    I J K L
    

    I Would like to get (from top left to bottom right):

    A
    EB
    IFC
    JGD
    KH
    L
    

    and (from the bottom left to top right):

    I
    JE
    KFA
    LGB
    HC
    D
    

    I already have a piece of code that works 3/4 of the way, but i cant seem to figure out what I am doing (wrong).

    //the array
    var TheArray = ['ABCD','EFGH','IJKL'];
    
    //amount of rows
    var RowLength = TheArray.length;
    //amount of colums
    var ColumnLength = TheArray[0].length;
    

    The code I have chops up the diagonals into 4 of these loops to get all the diagonals. It looks as 2 for loops with an if to not loop over unbound values. The pseudo code looks a bit like this:

    for(loop rows){
     var outputarray = [];
       for(loop columns){
          if(delimit for out of bound){
           var temprow = TheArray[something?];
           var tempvalue = temprow[something?];
           outputarray.push(tempvalue);
           }
       }
     //use values
    document.getElementById("theDiv").innerHTML += outputarray.join("")+"<br>";
    }
    

    I hope somebody can help me with this.

    • goodguy5
      goodguy5 about 8 years
      Just out of curiosity: Are you using an array of "strings" or an array of arrays?
    • jcubic
      jcubic about 8 years
      @goodguy5 it wouldn't matter because you can access string by index like arrays.
    • viperia
      viperia about 8 years
      @jcubic precisely, It is an array with strings, not an array of arrays, and i am using the index to get the right value from the string.
    • Yogi
      Yogi about 8 years
  • jcubic
    jcubic about 8 years
    If you run the snipped you will see that it missed entries from last column.
  • jcubic
    jcubic about 8 years
    You may want to reverse the string using str.split('').reverse().join('');
  • goodguy5
    goodguy5 about 8 years
    This is basically the same as what I did. I think I like yours better, though. And you just made me realize that I was imagining the array wrong (flipped the indexes)
  • viperia
    viperia about 8 years
    So close, i tried to implement your code and it seems alright, It works and I can understand what is happening. Thank you for that. But there is some problem when you have more rows in the array than the length of the strings. It does not return the last value. see this fiddle: jsfiddle.net/24xv3wvh/18
  • John Slegers
    John Slegers about 8 years
    @viperia : I just fixed that. Could you try again, with the code of my latest update?! ;-)
  • viperia
    viperia about 8 years
    Thank you, thank you, thank you. That did it. The trick to see which side of the matrix is longer did it.