转换表索引

时间:2016-01-21 20:42:44

标签: javascript arrays algorithm sorting matrix

我在数组中有数据被填充到表中。数组的索引对应于表中的位置,如下所示:

0,1,2        0,1,2       0,1,2
3,4,5    or  3,4,5   or  3,4,5
6,7,8        6,7         6

也就是说它从左到右,从上到下排序。我需要提出一个从左到右从上到下排序的功能。像这样:

0,3,6      
1,4,7
2,5,8

有几点需要注意。该表中可以包含任意数量的元素,但只有3列。

总而言之,我需要这样的事情:

Array indexes = [0,1,2,3,4,5,6,7,8]
Indexes after converting= [0,3,6,1,4,7,2,5,8]

现在我在某些情况下工作,就像有九个值一样。我真的很难为任意案件弄清楚这一点。我使用的是Javascript,但实际上任何语言的答案都会有所帮助。

对此的推理,是我需要以不同的方式布置我的表,但不想触摸HTML。我想重新排序索引,以便它们从上到下,从左到右排列。

到目前为止我所拥有的:

    scope.correctIndexData = function (data) {
        var colors = ['#92278f', '#f15a29', '#006838', '#27aae1', '#262262', '#754c29', '#ee2a7b', '#8dc63f', '#fff200'];
        var row = 0;
        var column = 0;

        var correctedData = new Array(data.length);
        for (var index = 0; index < data.length; index++) {
           var newIndex = scope.getCorrectedIndex(row,column,data);
            if(data.length>=10){
                correctedData[index] = data[newIndex];
            }
            else{
                correctedData[newIndex] = data[index];
                correctedData[newIndex].color = colors[newIndex];
            }

            if (column === 2) {
                column = 0;
                row++;
            } else {
                column++;
            }
        }
        return correctedData;
    };

    scope.getCorrectedIndex = function (row, column, data) {
        var newIndex;
        var rows = Math.ceil(data.length/3.0); //number of rows in table
        //handle the first row since there can be verying number of columns per row
        if (row === 0) { 
            if(column === 0){
                newIndex = 0;
            }
            else if (column === 1) {
                newIndex = rows;
            } else if(column == 2){
                if(data.length % 3 == 1){
                    newIndex = rows * 2 -1;
                }
                else{
                newIndex = rows * 2;    

            }
        }
        } else {
            if(data.length % 3 === 0){
                newIndex = (row) + (3 * column);
            }
            else if(data.length % 3 == 1){
                if(column === 0 || data.length % 7 === 0){
                    newIndex = (row) + (3 * column);
                }
                else{
                    newIndex = (row) + (3 * column) + 1;
                }
            }
            else{
                if(column === 0){
                    newIndex = (row) + (3 * column);
                }
                else{
                    newIndex = (row) + (3 * column) + 2;
                }
            }
        }
        return newIndex;
    };

2 个答案:

答案 0 :(得分:1)

试试这个:

// for your case, columns should equal 3
function transpose(array, columns) {
  var output = [];
  var rows = Math.ceil(array.length / columns);
  var i, j;

  for (j = 0; j < columns; j++) {
    for (i = 0; i < rows && i * columns + j < array.length; i++) {
      output.push(array[i * columns + j]);
    }
  }

  return output;
}

var input = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];

console.log(input.slice(0, 9).join());
console.log(transpose(input.slice(0, 9), 3).join());
console.log('----');
console.log(input.slice(0, 8).join());
console.log(transpose(input.slice(0, 8), 3).join());
console.log('----');
console.log(input.slice(0, 7).join());
console.log(transpose(input.slice(0, 7), 3).join());
console.log('----');
console.log(input.slice(0, 12).join());
console.log(transpose(input.slice(0, 12), 4).join());
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

第二个参数还允许您指定要转置的列数,如我在上一个示例中演示的那样。

修改

我真的不明白为什么你希望[0,1,2,3,4,5,6]转置到[0,3,5,1,4,6,2],所以我会尝试解释为什么结果应该是[0,3,6,1,4,2,5]似乎合乎逻辑:

0 1 2
3 4 5
6

根据您的换位算法,您应首先从上到下跟踪数字,然后从左到右跟踪,如下所示:

0 3 6
1 4
2 5

然后,当你通过从左到右阅读,然后从上到下阅读将其变成数组时,你会得到:

0 3 6 1 4 2 5

这正是我的算法所做的。如果你能解释为什么你的答案应该是0 3 5 1 4 6 2,那么这将有助于我按照你想要的方式调整我的算法。

答案 1 :(得分:0)

您需要按列进行迭代(即每3个成员)

scope.extract = function (data, col) {
  var ar = [];
  for (var i = col; i < data.length; i += 3) {
    ar.push(data[i]);
  }
  return ar;
}

scope.correctIndexData = function (data) {
  return scope.extract(data, 0).concat(scope.extract(data, 1)).concat(scope.extract(data,2))
}