我想提出一个很好的方法来获得如何在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']
我想首先向用户展示最重要的结果,但可能并不总是返回这些字段中的每一个。因此,我希望最重要的(由用户在其他一些代码中确定),如果可用的话,首先显示它们。
答案 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)
我认为这可能会有所帮助。 $('#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);
}
)
使用特殊处理先前已知重要结果的排序功能 - 如果结果中存在,则将它们排序到结果的开头。
答案 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?它包含几个用于操作这样的列表的实用程序。
在您的情况下,您可以:
使用filter()过滤所需的结果并将其存储在集合中。
var priorities = _.filter(['bob','david','steve','darrel','jim'],
function(pName){
if (pName == 'jim' || pName == 'steve' || pName == 'david') return true;
});
var leftovers = _.without(['bob','david','steve','darrel','jim'], 'jim', 'steve', 'david');
使用union()
联合前面步骤中的数组 var finalList = _.union(priorities, leftovers);