如何在JavaScript中对数组进行对角线遍历

31

我有一个字符串数组,想要按对角线遍历。
假设:

  • 每个字符串长度相同。
  • 数组可以是正方形或矩形,水平或垂直。

矩阵如下:

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

我想获得(从左上角到右下角):

A
EB
IFC
JGD
KH
L

并且(从左下到右上):

I
JE
KFA
LGB
HC
D

我已经有一段代码可以完成3/4的工作,但是我似乎无法弄清楚我做错了什么。

//the array
var TheArray = ['ABCD','EFGH','IJKL'];

//amount of rows
var RowLength = TheArray.length;
//amount of colums
var ColumnLength = TheArray[0].length;

我所拥有的代码将对角线划分为4个循环,以获取所有的对角线。它由2个for循环组成,使用if语句来避免循环未绑定的值。伪代码如下:

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

我希望有人能帮助我解决这个问题。


1
只是出于好奇:您是使用“字符串”数组还是数组的数组? - goodguy5
1
@goodguy5,这并不重要,因为你可以像访问数组一样通过索引访问字符串。 - jcubic
@jcubic,确切地说,这是一个字符串数组,而不是数组的数组,我正在使用索引从字符串中获取正确的值。 - viperia
9个回答

23

从左上角到右下角

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

var length = { "x" : theArray[0].length, "y" : theArray.length };
length.max = Math.max(length.x, length.y);

var temp, k, x, y;

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

(另请参见此代码片段)


从左下角到右上角

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

var length = { "x" : theArray[0].length, "y" : theArray.length };
length.max = Math.max(length.x, length.y);

var temp, k, x, y;

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

(请参见此Fiddle)


合并

由于两者只有一行差异,您可以轻松地将它们合并为一个函数:

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

function diagonal(data, fromBottom) {
    var length = { "x" : data[0].length, "y" : data.length };
    length.max = Math.max(length.x, length.y);

    var temp, k, x, y;

    var returnMe = [];

    for (k = 0; k <= 2 * (length.max - 1); ++k) {
        for (temp = [], y = length.y - 1; y >= 0; --y) {
            x = k - (fromBottom ? length.y - y : y);
            x >= 0 && x < length.x && temp.push(data[y][x]);
        }
        temp.length > 0 && returnMe.push(temp.join(''));
    }
    return returnMe;
}

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

(参见 this Fiddle


如果你运行这段代码,你会发现它错过了最后一列的条目。 - jcubic
非常接近了,我尝试实现你的代码,看起来没问题,它能够正常工作,我也能理解发生了什么。谢谢你。但是当数组中的行数超过字符串长度时,会出现一些问题。它无法返回最后一个值。请查看此链接:https://jsfiddle.net/24xv3wvh/18/ - viperia
@viperia:我刚刚修复了那个问题。你能否再试一次,使用我最新更新的代码?;-) - John Slegers
谢谢,谢谢,谢谢。就是这样了。找出矩阵哪一边更长的技巧解决了问题。 - viperia

6
这样做就可以了,将所需结果输出到屏幕上:

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

结果:

A
EB
IFC
JGD
KH
L

您可能想使用 str.split('').reverse().join('') 来反转字符串。 - jcubic
这基本上和我做的一样。不过我觉得你的更好。而且你刚才让我意识到我对数组的想象是错误的(索引颠倒了)。 - goodguy5

4

另一种解决方案:

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>');


2

使用索引:

[i][j-i]

i从0到M-1

j从0到i

当j++<N时

对于矩阵类型的Array[M][N]

然而,如果矩阵是矩形的,则可能会错过右下角的一些元素,您可能需要使用第二个嵌套的for循环来捕获它们。


2

试试这个

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


1

这是我尝试翻译“从左上到右下”的结果:

for (i=0; i<nbRows; i++) {
    x = 0; y = i;
    while (x < nbColumns && y >= 0) {
        print(array[x, y]);
        x++; y--;
    }
    print("\n");
}
for (i=1; i<nbColumns; i++) {
    x = i; y = nbRows - 1;
    while (x < nbColumns && y >=0) {
        print(array[x, y]);
        x++; y--;
    }
}

需要进行一些调整以适应JavaScript语法。

1
注意:这假设所有字符串大小相同,或者至少和第一个字符串一样大。
在一个二维数组(或者在这种情况下,一个字符串数组)中,对角线的索引加起来等于对角线的编号(就像行号)。00、01 10、02 11 20等等。
利用这种方法,对角线“行”的数量(从零开始)等于最大索引的总和,或者是(列长度+行长度-2)的总和。
因此,我的解决方案是遍历对角线行数并打印所有索引对,它们的总和等于当前对角线行。
var TheArray = ["ABCD","EFGH","IJKL"];
//amount of rows
var RowLength = TheArray.length;
//amount of colums
var ColumnLength = TheArray[0].length;

var text = ''
for (i = 0; i <= (RowLength+ColumnLength-2); i++){
    for (x = 0; x<=i; x++){
    if (TheArray[i-x] && TheArray[i-x][x]){
        text += TheArray[i-x][x];
    }
  }
  text += "<br/>";
}

document.getElementById('text').innerHTML = text;

JSFiddle链接


1

两条对角线的完整解决方案:

var TheArray = ['ABCD', 'EFGH', 'IJKL'];
var RowLength = TheArray.length;
var ColumnLength = TheArray[0].length;

// Diagonals
var diagonal = [[], []];
for (var i = 0; i < Math.min(RowLength, ColumnLength); i++) {
    diagonal[0].push({'row': 0-i, 'col': i});
    diagonal[1].push({'row': 0-i, 'col': 0-i});
}

// Entry points
// 1///
// 2///
// 3456
var points = [[], []];
for (var y = 0; y < RowLength; y++) {
    points[0].push({'row': y, 'col': 0});
}
for (var x = 1; x < ColumnLength; x++) {
    points[0].push({'row': RowLength - 1, 'col': x});
}

// Entry points
// \\\6
// \\\5
// 1234
for (var x = 0; x < ColumnLength; x++) {
    points[1].push({'row': RowLength - 1, 'col': x});
}
for (var y = RowLength - 2; y >= 0; y--) {
    points[1].push({'row': y, 'col': ColumnLength - 1});
}

var strings = [[], []];
for (var line = 0; line < diagonal.length; line++) {
    for (var point = 0; point < points[line].length; point++) {
        var inside = true;
        var index = 0;
        var string = '';
        while (inside && index < diagonal[line].length) {
            var row = points[line][point]['row'] + diagonal[line][index]['row'];
            var col = points[line][point]['col'] + diagonal[line][index]['col'];
            if (row >= 0 && row < RowLength && col >= 0 && col < ColumnLength) {
                string += TheArray[row][col];
                index++;
            } else {
                inside = false;
            }
        }
        strings[line].push(string);
    }
}

console.log(strings);

1

这应该适用于矩阵,即使是矩形的:

var array = ["ABCD", "EFGH", "IJKL"];
var arrOfArr = [];
var resultArray = [];
for (var i = 0; i < array.length; ++i) {
    arrOfArr.push(array[i].split(''));
}

var rows = arrOfArr.length;
var columns = arrOfArr[0].length;

var index = 0;

for (var i = 0; i < rows; ++i) {
    var k = 0;
    resultArray[index] = new Array();
    for (var j = i; j >= 0; --j) {
        resultArray[index].push(arrOfArr[j][k]);
        ++k;
        if ( k === columns) {
            break;
        }
    }
    resultArray[index] = resultArray[index].join('');
    ++index;
}

for (var j = 1; j < columns; ++j) {
    var k = rows - 1;
    resultArray[index] = new Array();
    for (var i = j; i < columns; ++i) {
        resultArray[index].push(arrOfArr[k][i]);
        --k;
        if ( k === -1) {
            break;
        }
    }
    resultArray[index] = resultArray[index].join('');
    ++index;
}
console.log(JSON.stringify(resultArray));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接