基于内部数组的值对外部数组进行排序,JavaScript。

11

我有一个由数组组成的数组,我想根据内部特定列中的值对外部数组进行排序。

我猜这听起来有点混乱,所以我将直接跳到示例。

初始数据:

var data = [
  [
    "row_1-col1",
    "2-row_1-col2",
    "c-row_1-coln"
  ],
  [
    "row_2-col1",
    "1-row_2-col2",
    "b-row_2-coln"
  ],
  [
    "row_m-col1",
    "3-row_m-col2",
    "a-row_m-coln"
  ]
];

按索引为1的列对数据进行排序

data.sortFuncOfSomeKind(1);

然后对象看起来会像这样;

var data = [
  [
    "row_2-col1",
    "1-row_2-col2",
    "b-row_2-coln"
  ],
  [
    "row_1-col1",
    "2-row_1-col2",
    "c-row_1-coln"
  ],
  [
    "row_m-col1",
    "3-row_m-col2",
    "a-row_m-coln"
  ]
];

根据索引为2的列对数据进行排序

data.sortFuncOfSomeKind(2);

那么对象看起来会像这样;

var data = [
  [
    "row_m-col1",
    "3-row_m-col2",
    "a-row_m-coln"
  ],
  [
    "row_2-col1",
    "1-row_2-col2",
    "b-row_2-coln"
  ],
  [
    "row_1-col1",
    "2-row_1-col2",
    "c-row_1-coln"
  ]
];

这个大问题

你知道是否存在现有的解决方案,或者我必须自己编写一个?如果是的话,哪种排序算法最容易使用?快速排序?

_L


3个回答

16

Array#sort(参见规范的第15.4.4.11节或MDC)接受一个可选的函数参数,用于比较两个条目以进行排序。该函数应返回-1,如果第一个参数“小于”第二个参数,返回0,如果它们相等,或返回1,如果第一个参数“大于”第二个参数。因此:

outerArray.sort(function(a, b) {
    var valueA, valueB;

    valueA = a[1]; // Where 1 is your index, from your example
    valueB = b[1];
    if (valueA < valueB) {
        return -1;
    }
    else if (valueA > valueB) {
        return 1;
    }
    return 0;
});

(显然,您可以压缩代码以使其更简洁;我为了清晰起见保持了冗长。)


8
这里有一个解决方案,不需要单独的变量来包含索引。
var arr = [.....]
arr.sort((function(index){
    return function(a, b){
        return (a[index] === b[index] ? 0 : (a[index] < b[index] ? -1 : 1));
    };
})(2)); // 2 is the index

这将按照索引2进行排序


1
你应该将那个 = 改成 ===。比较运算符不喜欢被误认为是赋值运算符。 - awgy
根据您的需求将其更改为===== - T.J. Crowder
是的,那里有一个小错误 - 现在已经修复了。 - Sean Kinsey
我倾向于建议使用 ===,因为得到了 Douglas Crockford 的一些建议:“几乎总是最好使用 ===!== 运算符。==!= 运算符会进行类型强制转换。特别是,不要使用 == 来与假值进行比较。” 但我同意有时可能需要进行类型强制转换。(参见:http://javascript.crockford.com/code.html) - awgy
但在这种情况下,所有的值都是字符串,所以这并不重要。而且,> 和 < 操作符必须强制转换类型,因为很难确定字符串 "2" 和数字 3 之间哪个更“先”。 - Sean Kinsey
显示剩余2条评论

2

这里曾经有一个排序实现,它返回了一个简单的x<y比较的结果。这种解决方案不被鼓励使用,本文仅保留后续讨论。


@T.J.Crowder:当我运行该代码时,它正确地输出了“one - three - two”,“two - three - one”,“one - three - two”。这正是您从字母排序中期望的结果。您没有看到这个结果吗?http://jsbin.com/ovoze3 - David Hedlund
@T.J. Crowder: 此外:我的 - http://jsbin.com/ovoze3/edit 你的 - http://jsbin.com/ovoze3/2/edit。在它们中点击“预览”>“运行”,它们将产生完全相同的结果。 - David Hedlund
1
@David:请看第5版规范(http://www.ecma-international.org/publications/standards/Ecma-262.htm)的15.4.4.11节:"比较函数应该是一个接受两个参数x和y并返回负值(如果x<y),零(如果x=y)或正值(如果x>y)的函数。",以及第11.8.5节(关于>):"比较产生 true、false 或 undefined(这表示至少有一个操作数是 NaN)。" 因此,从函数中返回 truefalse 会导致未定义的行为,并且由于该函数必须具有三种可能的结果,因此会出现不正确的行为。 - T.J. Crowder
@David:我相信如果你编辑一下,它就不会再被踩了。 - T.J. Crowder
我读了这个,当时想着“没可能会成功...”,但它居然就成功了...太棒了,非常感谢,你帮我省去了自己实现排序的麻烦,已点赞 :)。 - Trevor Hart
显示剩余9条评论

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