生成确定排序等级的JS数组

时间:2016-01-05 20:12:12

标签: javascript jquery

使用复杂数组(对于列和行中显示的表格数据的用例),我可以说我有一些值:

files:
  "/tmp/45_nginx_https_rw.sh":
    owner: root
    group: root
    mode: "000644"
    content: |
      #! /bin/bash

      CONFIGURED=`grep -c "return 301 https" /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf`

      if [ $CONFIGURED = 0 ]
        then
          sed -i '/listen 8080;/a \    if ($http_x_forwarded_proto = "http") { return 301 https://$host$request_uri; }\n' /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf
          logger -t nginx_rw "https rewrite rules added"
          exit 0
        else
          logger -t nginx_rw "https rewrite rules already set"
          exit 0
      fi

container_commands:
  00_appdeploy_rewrite_hook:
    command: cp -v /tmp/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/appdeploy/enact
  01_configdeploy_rewrite_hook:
    command: cp -v /tmp/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/configdeploy/enact
  02_rewrite_hook_perms:
    command: chmod 755 /opt/elasticbeanstalk/hooks/appdeploy/enact/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/configdeploy/enact/45_nginx_https_rw.sh
  03_rewrite_hook_ownership:
    command: chown root:users /opt/elasticbeanstalk/hooks/appdeploy/enact/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/configdeploy/enact/45_nginx_https_rw.sh

返回匹配数组的最佳方法是在正确(维护)的顺序中将值与进行排名?在这种情况下,排名顺序将从最高到最低。

例如,最终结果数组为:

var values = [
    [234, 386, 21, 38],
    [-23, 58, 106, 0],
    [45, -48, 506, 23],
    [109, 168, 42, 111]
];

请注意结果如何按列垂直排序。

我想在大数据集中使用它,因此我的目标是获得最快性能的指导/提示。

-

对于上下文:我的第一次尝试是使用索引值映射原始数组,但我不确定从那里去哪里:

[
    [1, 1, 4, 2],
    [4, 3, 2, 4],
    [3, 4, 1, 3],
    [2, 2, 3, 1]
];

3 个答案:

答案 0 :(得分:3)

基本上,诀窍是在排序后保留原始索引。我先将它们迭代到数据结构中,对其进行排序,然后从结果中重建二维数组结构。

我没有做任何检查以确保输入格式正确,假设所有行都与第一行的宽度相同。

可能完成的优化是在排序期间将原始值转换为数据结构,这将消除数组的传递。我没有看到一种简单的方法来做到这一点而不会失去一些简洁性和可读性,这将是一个非常小的收益。

var values = [
    [234, 386, 21, 38],
    [-23, 58, 106, 0],
    [45, -48, 506, 23],
    [109, 168, 42, 111]
];

function buildRanking(arr) {
  var result = [];
  for(var col = 0; col < arr[0].length; col++) {
    //everything inside this for loop is per column

    //first use map function to turn the column into an array of objects
    //each holding the value and the current index. [{value: 234, index: 1}, etc..]
    var sortableStructure = values.map(function(val, i) {
      return { value : val[col], index : i };
    });

    //Sort function to sort my sortableStructure in place on the values
    sortableStructure.sort(function(a, b) {
      return b.value - a.value;
    });

    //now iterate over the sortable strucutre
    for(var i = 0; i < sortableStructure.length; i++) {
      //this ugly bit just makes sure arrays are initialized for each row as needed
      if(typeof result[sortableStructure[i].index] === 'undefined')
          result[sortableStructure[i].index] = [];

     //for the current item in the sortableStructure, get the index
     //access the result element corresponding to that index 
     //(the original position of this sorted value) and push in 
     //the current index (sort order) + 1 (to switch from zero-based to one-based)
      result[sortableStructure[i].index].push(i + 1);
    }
  }
  return result;
}

//To provide visible output.
document.write(JSON.stringify(buildRanking(values)).split('],[').join('],<br/>['));

答案 1 :(得分:0)

首先通过这个并且高度未优化,但这是一个松散的实现,我一步一步地做。

function sort(rows) {

  var columns = [];

   /* Invert rows and columns */

  for (var i = 0, row; i < rows.length; i++) {
    row = rows[i];
    for (var j = 0, col; j < row.length; j++) {
      col = rows[i][j];
      columns[j] = columns[j] || [];
      columns[j][i] = col;
    }
  }

  /* Sort by descending order, returning index */

  var sortedColumns = columns.slice(0).map(function(column, i) {
    return column.slice(0).sort(function(a, b) {
      return b - a;
    }).map(function(value, j, sortedColumn) {
      return sortedColumn.indexOf(column[j]) + 1;
    });
  });


  /* Invert rows and columns back again */

  var sortedRows = [];

    for (var i = 0, row; i < sortedColumns.length; i++) {
    row = sortedColumns[i];
    for (var j = 0, col; j < row.length; j++) {
      col = sortedColumns[i][j];
      sortedRows[j] = sortedRows[j] || [];
      sortedRows[j][i] = col;
    }
  }

  return sortedRows;
}

var values = [
  [234, 386, 21, 38],
  [-23, 58, 106, 0],
  [45, -48, 506, 23],
  [109, 168, 42, 111]
];

var expected = [
  [1, 1, 4, 2],
  [4, 3, 2, 4],
  [3, 4, 1, 3],
  [2, 2, 3, 1]
];

var sorted = sort(values);

console.log(sorted.toString() === expected.toString()); // true

JSFiddle演示:https://jsfiddle.net/7ek6pz63/2/

答案 2 :(得分:0)

假设列要按降序排序,结果基于1,那么这应该有效。

var values = [
        [234, 386, 21, 38],
        [-23, 58, 106, 0],
        [45, -48, 506, 23],
        [109, 168, 42, 111]
    ];

function getX(array) {
    var length = array[0].length,
        result = Array.apply(null, { length: array.length }).map(function () { return []; }),
        temp, i;

    for (i = 0; i < length; i++) {
        temp = [];
        array.forEach(function (a, j) {
            temp.push({ v: a[i], i: j });
        });
        temp.sort(function (a, b) {
            return b.v - a.v;
        }).forEach(function (a, j) {
            result[a.i][i] = j + 1;
        });
    }
    return result;
}

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