简体   繁体   English

根据另一个数组按顺序排序数组

[英]Sort array by order according to another array

I have an object that is being returned from a database like this: [{id:1},{id:2},{id:3}] . 我有一个从这样的数据库返回的对象: [{id:1},{id:2},{id:3}] I have another array which specified the order the first array should be sorted in, like this: [2,3,1] . 我有另一个数组,它指定了第一个数组应该排序的顺序,如下所示: [2,3,1]

I'm looking for a method or algorithm that can take in these two arrays and return [{id:2},{id:3},{id:1}] . 我正在寻找一种可以接收这两个数组并返回[{id:2},{id:3},{id:1}]的方法或算法。 Ideally it should be sort of efficient and not n squared. 理想情况下,它应该是有效的而不是n平方。

If you want linear time, first build a hashtable from the first array and then pick items in order by looping the second one: 如果你想要线性时间,首先从第一个数组构建一个哈希表,然后通过循环第二个数组来顺序选择项:

 data = [{id:5},{id:2},{id:9}] order = [9,5,2] hash = {} data.forEach(function(x) { hash[x.id] = x }) sorted = order.map(function(x) { return hash[x] }) document.write(JSON.stringify(sorted)) 

  function sortArrayByOrderArray(arr, orderArray) { return arr.sort(function(e1, e2) { return orderArray.indexOf(e1.id) - orderArray.indexOf(e2.id); }); } console.log(sortArrayByOrderArray([{id:1},{id:2},{id:3}], [2,3,1])); 

In your example, the objects are initially sorted by id , which makes the task pretty easy. 在您的示例中,对象最初按id排序,这使得任务非常简单。 But if this is not true in general, you can still sort the objects in linear time according to your array of id values. 但是,如果这种情况一般不正确,您仍然可以根据您的id值数组以线性时间对对象进行排序。

The idea is to first make an index that maps each id value to its position, and then to insert each object in the desired position by looking up its id value in the index. 我们的想法是首先创建一个索引,将每个id值映射到它的位置,然后通过在索引中查找其id值将每个对象插入所需的位置。 This requires iterating over two arrays of length n , resulting in an overall runtime of O(n) , or linear time. 这需要迭代两个长度为n数组,从而导致总运行时间为O(n)或线性时间。 There is no asymptotically faster runtime because it takes linear time just to read the input array. 没有渐近更快的运行时间,因为它只需要读取输入数组的线性时间。

 function objectsSortedBy(objects, keyName, sortedKeys) { var n = objects.length, index = new Array(n); for (var i = 0; i < n; ++i) { // Get the position of each sorted key. index[sortedKeys[i]] = i; } var sorted = new Array(n); for (var i = 0; i < n; ++i) { // Look up each object key in the index. sorted[index[objects[i][keyName]]] = objects[i]; } return sorted; } var objects = [{id: 'Tweety', animal: 'bird'}, {id: 'Mickey', animal: 'mouse'}, {id: 'Sylvester', animal: 'cat'}], sortedIds = ['Tweety', 'Mickey', 'Sylvester']; var sortedObjects = objectsSortedBy(objects, 'id', sortedIds); // Check the result. for (var i = 0; i < sortedObjects.length; ++i) { document.write('id: '+sortedObjects[i].id+', animal: '+sortedObjects[i].animal+'<br />'); } 

To my understanding, sorting is not necessary; 据我了解,没有必要进行分类; at least in your example, the desired resulting array can be generated in linear time as follows. 至少在您的示例中,可以按线性时间生成所需的结果数组,如下所示。

var Result;
for ( var i = 0; i < Input.length; i++ )
{
    Result[i] = Input[Order[i]-1];
}

Here Result is the desired output, Input is your first array and Order the array containing the desired positions. 这里Result是所需的输出, Input是你的第一个数组,并Order包含所需位置的数组。

var objArray = [{id:1},{id:2},{id:3}];
var sortOrder = [2,3,1];

var newObjArray = [];
for (i in sortOrder) {
    newObjArray.push(objArray[(sortOrder[i]) - 1])
};

Why not just create new array and push the value from second array in?? 为什么不创建新数组并从第二个数组中推送值? Correct me if i wrong 如果我错了,请纠正我

array1 = [];
array2 = [2,3,1];

for ( var i = 0; i < array2 .length; i++ )
{
    array1.push({
         id : array2[i]
     })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM