利用字符串实现数组的复杂排序

一. 场景

有这样一个数组:

[
   {inuse: '0', order: 10},
   {inuse: '1', order: 10},
   {inuse: '0', order: 9},
   {inuse: '1', order: 8},
   ...
]

现在需要根据inuse和order的值进行排序,排序规则是:inuse为’0′的数据排在前面,为‘1’的排在后面,且为’0′和’1′的数据还要按照order的大小进行降序排列,预期结果如下:

[
   {inuse: '1', order: 10},
   {inuse: '1', order: 8},
   {inuse: '0', order: 10},
   {inuse: '0', order: 9},
   ...
]

二. 我的解决思路

排序规则的特点:先比较inuse的大小,如果inuse的值相同,再继续比较order的大小,这个比较特点是不是让你觉得非常熟悉,像什么?对,就是字符串比较(逐位比较),说到这里,方法已很明确,即将inuse和order值进行连接,然后对连接后的值进行比较即可,如下:

<script>
var arr = [
        {inuse: '0', order: 10},
        {inuse: '1', order: 10},
        {inuse: '0', order: 9},
        {inuse: '1', order: 8}
];
arr.sort(function(a, b) {
   var result,
        aOrder = a.inuse + a.order,
        bOrder = b.inuse + b.order;

   if (aOrder > bOrder) {
        result = 1;
   } else if (aOrder === bOrder) {
        result = 0;
   } else {
        result = -1;
   }
   return result;
});
// 在该例中,实际上是在对['010', '110', '09', '18']进行排序
</script>

三. update

这种字符串的方式适用场景有限(inuse只有两个值且order值等长),对于怿飞和jumkey提到的问题,字符串的方式不太好解决,不过换个方式就可以了:

<script>
var arr = [
        {inuse: '1', order: 11},
        {inuse: '11', order: 1},
        {inuse: '0', order: 9},
        {inuse: '0', order: 10}
];
var weight = 10000;
arr.sort(function(a, b) {
   var result,
        aOrder = a.inuse * weight + a.order,
        bOrder = b.inuse * weight + b.order;

   if (aOrder > bOrder) {
        result = 1;
   } else if (aOrder === bOrder) {
        result = 0;
   } else {
        result = -1;
   }
   return result;
});
</script>

你有更好的思路吗???

,

Comments

怿飞 at 2010年03月28日 1:02 上午

按照这个思路,对于下面这个数组的排序,就出现问题了:
[{inuse: '11', order: 1},
{inuse: '1', order: 11}]

Author comment by Tcer at 2010年03月28日 2:52 下午

@怿飞: 的确,对于你提供的例子确实有问题,不过在我遇到的实际需求中,inuse的值只有’0′和’1′这两个值,这个方法的适用场景还是蛮有限的,呵呵!

遇春 at 2010年03月28日 11:47 下午

arr.sort(function(a,b){
return a.inuse>b.inuse ? -1 : a.inuse b.order ? -1 : 0
});
这样会不会简单点

遇春 at 2010年03月28日 11:50 下午

发现一个xss漏洞哦,html标签没有转移,重新回复刚才的内容:
arr.sort(function(a,b){
return a.inuse > b.inuse ? -1 : a.inuse < b.inuse ? 1 : a.order > b.order ? -1 : 0
});

释然 at 2010年03月29日 11:02 下午

方法很巧妙

jumkey at 2010年04月2日 9:24 下午

“010″”010″

你这个比较只能比较等长数值

不同长度的数值要前面补0才行吧。

jumkey at 2010年04月2日 9:26 下午

“010″《”09″而”011″》”010″

晕括号被和谐了

Leave a comment!