【发布时间】:2014-12-04 09:05:08
【问题描述】:
我有一个从这样的数据库返回的对象:[{id:1},{id:2},{id:3}]。我有另一个数组,它指定了第一个数组的排序顺序,如下所示:[2,3,1]。
我正在寻找可以接收这两个数组并返回[{id:2},{id:3},{id:1}] 的方法或算法。理想情况下,它应该是高效的,而不是 n 平方。
【问题讨论】:
标签: javascript algorithm sorting
我有一个从这样的数据库返回的对象:[{id:1},{id:2},{id:3}]。我有另一个数组,它指定了第一个数组的排序顺序,如下所示:[2,3,1]。
我正在寻找可以接收这两个数组并返回[{id:2},{id:3},{id:1}] 的方法或算法。理想情况下,它应该是高效的,而不是 n 平方。
【问题讨论】:
标签: javascript algorithm sorting
如果你想要线性时间,首先从第一个数组构建一个哈希表,然后通过循环第二个数组来按顺序选择项目:
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]));
【讨论】:
在您的示例中,对象最初按id 排序,这使得任务非常简单。但是,如果这不是一般情况,您仍然可以根据您的 id 值数组以线性时间对对象进行排序。
这个想法是首先创建一个索引,将每个id 值映射到其位置,然后通过在索引中查找其id 值将每个对象插入到所需位置。这需要迭代两个长度为n 的数组,从而导致整体运行时间为O(n),或线性时间。没有渐近更快的运行时间,因为读取输入数组需要线性时间。
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 />');
}
【讨论】:
据我了解,排序不是必需的;至少在您的示例中,可以在线性时间内生成所需的结果数组,如下所示。
var Result;
for ( var i = 0; i < Input.length; i++ )
{
Result[i] = Input[Order[i]-1];
}
这里Result 是所需的输出,Input 是您的第一个数组,Order 是包含所需位置的数组。
【讨论】:
id 值排序并且它们是连续的。
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])
};
【讨论】:
为什么不直接创建新数组并将第二个数组中的值推入?如果我错了,请纠正我
array1 = [];
array2 = [2,3,1];
for ( var i = 0; i < array2 .length; i++ )
{
array1.push({
id : array2[i]
})
}
【讨论】: