Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对给定预定义顺序的字符串列表进行排序_Javascript_Sorting_Time Complexity - Fatal编程技术网

Javascript 对给定预定义顺序的字符串列表进行排序

Javascript 对给定预定义顺序的字符串列表进行排序,javascript,sorting,time-complexity,Javascript,Sorting,Time Complexity,我有一系列的颜色,我想按顺序排列。但是,我不想使用它们的“自然”顺序对它们进行排序,而是将它们保持在以下顺序: var order = ['white', 'yellow', 'violet', 'blue', 'orange', 'red', 'maroon', 'brown', 'black']; 例如,对这个数组进行排序 var items = ['blue', 'violet', 'white', 'black', 'orange']; 应该还 ['white', 'violet',

我有一系列的颜色,我想按顺序排列。但是,我不想使用它们的“自然”顺序对它们进行排序,而是将它们保持在以下顺序:

var order = ['white', 'yellow', 'violet', 'blue', 'orange', 'red', 'maroon', 'brown', 'black'];
例如,对这个数组进行排序

var items = ['blue', 'violet', 'white', 'black', 'orange'];
应该还

['white', 'violet', 'blue', 'orange', 'black'];
以下是我目前掌握的情况:

var itemsInOrder = [];

for (var i=0; i<order.length; i++) {
    if (items.indexOf(order[i]) > -1) {
        itemsInOrder.push(order[i]);
    }
}
var itemsInOrder=[];
对于(变量i=0;i-1){
itemsinoorder.push(订单[i]);
}
}
我不确定它的伸缩性有多好-如果
order
有100或1000个元素,而“items”有10个呢


什么是一种好的、可扩展的方法来实现这一点?

正如@shmiddy在一篇评论中指出的,一种简单的方法是使用库
sort
函数和自定义比较器,如下所示:

items.sort(function(a,b) {
   return order.indexOf(a) - order.indexOf(b);
});
我从这个开始。如果足够快,太好了!随它去吧

从时间复杂性的角度来看,让我们假设您有一个由n个元素组成的列表要排序,而主排序中有k个元素。然后使用自定义比较器调用
sort
将进行O(n logn)比较,由于扫描列表的成本,每个比较都需要O(k)时间。这给出了运行时间O(knlogn)。假设k很小——也就是说,您的主列表不会太长——这是非常好的

如果k很大——例如,如果你对世界上所有的城市都有一个固定的排序,或者类似的东西——那么这种方法不可能很好地扩展。在这种情况下,您可能希望通过创建一个直接将要排序的所有内容映射到其索引的字典来为问题添加另一层间接寻址。有一种方法可以做到这一点:

var indexMap = {};
for (var i = 0; i < order.length; i++) {
    indexMap[order[i]] = i;
}

items.sort(function(a,b) {
   return indexMap[a] - indexMap[b];
});
var indexMap={};
对于(变量i=0;i

这具有时间复杂性O(k+n log n),因此对于非常大的k,速度可能会明显加快。

除了templatetypedef的答案之外,还有一点是,如果预定义的是“部分”,例如列表中的某些项目无法按预定义的顺序排序,然后你可以把它们从你的列表中分离出来,然后把它们连接到列表的末尾

var items = [3, 2, 3, 2, 1, 4, 5, 1, 2, 3]
var order = [1, 2, 3]
var unordered = items.filter(t => order.indexOf(t) === -1);
var ordered = items.filter(t => order.indexOf(t) !== -1);
ordered.sort(function(a,b) {
   return order.indexOf(a) - order.indexOf(b);
});
var final = ordered.concat(unordered)
console.log(final)
// [ 1, 1, 2, 2, 2, 3, 3, 3, 4, 5 ]

如果不执行此步骤,那么排序实际上会将无序项放在列表的前面,我不知道如何更改它以将它们移回末尾,而不首先过滤掉它们。

如果有人正在寻找比Colin D更简单的代码来排序数组并在末尾添加未知项,下面是另一个例子:

let list = ["A", "F", "Banana", "rules", "L", "Juice", "Z"]
let order = ["Banana", "Juice", "rules"]

list.sort((a, b) => {
  if (order.indexOf(a) === -1) return 1
  if (order.indexOf(b) === -1) return -1
  return order.indexOf(a) - order.indexOf(b)
})

console.log(list)

这将记录:
[“香蕉”、“果汁”、“规则”、“A”、“F”、“L”、“Z”]
var itemsinoorder=items.slice().sort(…)
如果您不想变异的话items@Shmiddty你能详细解释一下items.sort()是如何操作的吗变异
数组。prototype.sort
将更新正在排序的数组的索引,而不是创建并返回新的(已排序的)数组。