按首选顺序对数组进行排序

时间:2012-03-09 03:42:43

标签: javascript jquery

我想提出一个很好的方法来获得如何在javascript中对数组进行排序的“建议”命令。

所以说我的第一个数组看起来像这样:

['bob','david','steve','darrel','jim']

现在我关心的是,排序结果是按此顺序开始的:

['jim','steve','david']

之后,我希望剩余的值以原始顺序显示。

所以我希望结果是:

['jim','steve','david','bob','darrel']

我有一个与之通信的API,我想在顶部的列表中向我展示重要的结果。在那之后,我希望他们只是按原来的顺序归还。

如果使用像jQuery这样的javascript框架可以轻松实现这一点,我也想听听。谢谢!

为清晰起见编辑:

我想假设我不想保证数组中提供的值。

所以在原始示例中,如果提供的是:

['bob','steve','darrel','jim']

我想通过以下方式对其进行排序:

['jim','steve','david']

由于'david'不在提供的数组中,我希望结果将其排除。

Edit2更清晰: 我正在努力实现的一个实际例子:

API将返回如下内容:

['Load Average','Memory Usage','Disk Space']

我想首先向用户展示最重要的结果,但可能并不总是返回这些字段中的每一个。因此,我希望最重要的(由用户在其他一些代码中确定),如果可用的话,首先显示它们。

7 个答案:

答案 0 :(得分:3)

这样的事情应该有效:

var presetOrder = ['jim','steve','david']; // needn't be hardcoded

function sortSpecial(arr) {
   var result = [],
       i, j;
   for (i = 0; i < presetOrder.length; i++)
      while (-1 != (j = $.inArray(presetOrder[i], arr)))
         result.push(arr.splice(j, 1)[0]);
   return result.concat(arr);
}

var sorted = sortSpecial( ['bob','david','steve','darrel','jim'] );

我允许在处理的数组中出现多次“特殊”值,并假设只要它们按照{{1}中定义的顺序拖拽到前面,就应该保留重复值。 }。

注意:我之前只使用了jQuery's $.inArray()而不是Array.indexOf(),因为在IE9之前IE不支持后者,并且您使用“jQuery”标记了您的问题。如果您不关心旧IE,或者使用shim,您当然可以使用presetOrder

答案 1 :(得分:0)

http://tinysort.sjeiti.com/

我认为这可能会有所帮助。 $('#yrDiv').tsort({place:'start'});会在一开始就添加您的重要列表。

您也可以按照自己喜欢的方式使用此功能进行排序。

答案 2 :(得分:0)

var important_results = {
  // object keys are the important results, values is their order
  jim: 1,
  steve: 2,
  david: 3
  };

// results is the orig array from the api
results.sort(function(a,b) {
    // If compareFunction(a, b) is less than 0, sort a to a lower index than b.
    // See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort
    var important_a = important_results[a], 
        important_b = important_results[b],
        ret;

    if (important_a && !important_b) {ret = -1}
    else if (important_b && !important_a) {ret = 1}
    else if (important_a && important_b) {ret = important_a - important_b}
    else {ret = 0}; // keep original order if neither a or b is important

    return(ret);
  }
)

使用特殊处理先前已知重要结果的排序功能 - 如果结果中存在,则将它们排序到结果的开头。

  • important_results中的项目不必在结果中

答案 3 :(得分:0)

这是一个简单的测试页面:

<html>
<head>
<script language="javascript">
function test()
{
   var items = ['bob', 'david', 'steve', 'darrel', 'jim'];

   items.sort(function(a,b)
        {
           var map = {'jim':-3,'steve':-2,'david':-1};
           return map[a] - map[b];
         });
    alert(items.join(','));
}
</script>
</head>
<body>
<button onclick="javascript:test()">Click Me</button>
</body>
</html>

它适用于大多数浏览器,因为javascript 通常使用所谓的stable sort algorithm,其定义功能是保留原始订单等效项。但是,我知道有例外。通过使用每个剩余项目的数组索引来保证稳定性,因为它是a1 / b1值。

答案 4 :(得分:0)

现场演示(jsfiddle似乎失败了)

http://jsbin.com/eteniz/edit#javascript,html

var priorities=['jim','steve','david'];

var liveData=['bob','david','steve','darrel','jim'];


var output=[],temp=[];  
for ( i=0; i<liveData.length; i++){
    if( $.inArray( liveData[i], priorities) ==-1){
        output.push( liveData[i]);
    }else{
        temp.push( liveData[i]);
    }
}
var temp2=$.grep( priorities, function(name,i){
        return $.inArray( name, temp) >-1;                             
});

output=$.merge( temp2, output);

答案 5 :(得分:0)

可以有另一种基于订单的排序方式,值也可以是要使用的对象

const inputs = ["bob", "david", "steve", "darrel", "jim"].map((val) => ({
  val,
}));
const order = ["jim", "steve", "david"];

const vMap = new Map(inputs.map((v) => [v.val, v]));
const sorted = [];
order.forEach((o) => {
  if (vMap.has(o)) {
    sorted.push(vMap.get(o));
    vMap.delete(o);
  }
});
const result = sorted.concat(Array.from(vMap.values()));
const plainResult = result.map(({ val }) => val);

答案 6 :(得分:-1)

您是否考虑过使用Underscore.js?它包含几个用于操作这样的列表的实用程序。

在您的情况下,您可以:

  1. 使用filter()过滤所需的结果并将其存储在集合中。

    var priorities = _.filter(['bob','david','steve','darrel','jim'], function(pName){ if (pName == 'jim' || pName == 'steve' || pName == 'david') return true; });

  2. 使用without()

    获取其他结果的副本

    var leftovers = _.without(['bob','david','steve','darrel','jim'], 'jim', 'steve', 'david');

  3. 使用union()

    联合前面步骤中的数组

    var finalList = _.union(priorities, leftovers);