在javascript中按关系对数组排序
我想对数组进行排序 数组中的项具有关系 例如,在javascript中按关系对数组排序,javascript,arrays,algorithm,sorting,object,Javascript,Arrays,Algorithm,Sorting,Object,我想对数组进行排序 数组中的项具有关系 例如,list[5]应该在list[9]之前,但在list[3]之后 样本中的期望值仅用于测试。它实际上并不存在 下面是一个带有关系和预期索引的示例数组 var list = [{ id: '0001', before: '0002', expected: 0 }, { id: '0002', before: '0007', after: '0001', expected: 4 }, { id: '0003', be
list[5]
应该在list[9]之前,但在list[3]之后
样本中的期望值仅用于测试。它实际上并不存在
下面是一个带有关系和预期索引的示例数组
var list = [{
id: '0001',
before: '0002',
expected: 0
}, {
id: '0002',
before: '0007',
after: '0001',
expected: 4
}, {
id: '0003',
before: '0006',
after: '0001',
expected: 2
}, {
id: '0004',
after: '0007',
expected: 11
}, {
id: '0005',
before: '0003',
after: '0001',
expected: 1
}, {
id: '0006',
before: '0002',
after: '0001',
expected: 3
}, {
id: '0007',
before: '00010',
after: '0002',
expected: 5
}, {
id: '0008',
before: '00012',
after: '0007',
expected: 9
}, {
id: '0009',
before: '0011',
after: '0001',
expected: 7
}, {
id: '0010',
before: '0009',
after: '0007',
expected: 6
}, {
id: '0011',
before: '0008',
after: '0001',
expected: 8
}, {
id: '0012',
before: '0004',
after: '0010',
expected: 10
}];
如果我理解正确,
expected
是您希望元素成为的索引吗?在这种情况下,您可以使用带有自定义排序功能的.sort()
list.sort(function (a, b) {
var ae = a.expected,
be = b.expected;
if (ae > be) return 1;
if (ae < be) return -1;
if (ae === be) return 0;
});
list.sort(函数(a,b){
var ae=a.预期值,
be=b.预期;
如果(ae>be)返回1;
如果(ae
(如果您愿意,可以缩短该块,但要牺牲可读性。)部分回答,太长,无法发表评论。你可能已经明白了,我只是希望它能帮助别人找到解决办法
Object.defineProperty(Array.prototype,"move",{
value: function(from,to) {
var x = this.splice(from,1);
this.splice(to,0,x[0]);
}
});
var list = ['a','b','c','d','e'];
// move the index 1 (b) to position 3 (after d)
list.move(1,3); // acdbe
祝你好运。关于Jan Turoň的扩展:下面是一个例子,说明你的问题(在有向无环图中找到总顺序)是如何无法解决的:
var list = [{ id:A, before:B }, // "First" in total order
{ id:B, after:A }, // "Last" in total order
{ id:C, after:A, before:B },
{ id:D, after:A, before:B }];
在C
和D
之间没有总的顺序:你可以称它们相等,但是如果你有一个列表D0->D1->D2
,而不是D
,会怎么样
根据您的问题类型,这可以通过预处理来解决:将阶数为2的节点路径减少为单个节点,并通过阶数为2的相同节点调用并行路径(也将减少为单个节点)。在这样的预处理结束时,您将看到一棵树——在您的情况下,它应该是一个列表/路径(或者一个节点,因为您减少了阶数为2的顶点的路径)
请注意,“之前”和“之后”的信息是多余的:您实际上只需要其中一个。语句“A在B之前”相当于“B在A之后”,无环图只需要反映“之前”或“之后”的方向。然后,您要查找的是包含所有节点的图形中的路径(因为它们是在“之前”或“之后”定向的,所以您会自动获得从第一个到最后一个的路径(如果存在这样的路径):
//首先为“Y之前的X”构建邻接列表
变量befores={};
对于(变量i=0;i“X之前的Y”
插入(项目id,项目之前);
}
//构建完整的图形作为查找表
//id在查找中的所有元素之前[id]
var查找={};
对于(变量i=0;i
自己测试一下:
var列表=[{
id:'0001',在'0002'之前,应为:0}{
id:'0002',在'0007'之前,'0001'之后,应为:4}{
id:'0003',在'0006'之前,'0001'之后,应为:2}{
id:'0004',在'0007'之后,应为:11}{
id:'0005',在'0003'之前,'0001'之后,应为:1}{
id:'0006',在'0002'之前,'0001'之后,应为:3}{
id:'0007',在'0010'之前,'0002'之后,应为:5}{
id:'0008',在'0012'之前,'0007'之后,应为:9}{
id:'0009',在'0011'之前,'0001'之后,应为:7}{
id:'0010',在'0009'之前,'0007'之后,应为:6}{
id:'0011',在'0008'之前,'0001'之后,应为:8}{
id:'0012',在'0004'之前,'0010'之后,预期为:10
}];
//重复使用变量
var count=list.length;
var out=document.getElementById(“out”);
函数到htmlitem(项){
var结果=项目。预期+“(”;
如果(item.after)结果+=item.after+“”;
结果+=“”+item.id+“”;
如果(item.before)结果+=“”+item.before;
结果+=”;
返回结果;
}
函数tohtmlist(列表){
var result=“”;
对于(变量i=0;i”;
}
结果+=“”;
返回结果
// First build the adjacency list for "X before Y"
var befores = { };
for(var i = 0; i < count; ++i)
befores[list[i].id] = null;
function insert(before, after) {
if(!before || !after)
return;
befores[before] = { next:befores[before], id:after };
}
for(var i = 0; i < count; ++i) {
var item = list[i];
insert(item.after, item.id); // "X after Y" -> "Y before X"
insert(item.id, item.before);
}
// build complete the graph as a lookup table
// id is "before" all elements in lookup[id]
var lookup = { };
for(var i = 0; i < count; ++i) {
var id = list[i].id;
var beforeList = [id];
var beforeSet = { };
beforeSet[id] = 1;
// use "A before B" and "B before C" to gain "A before C"
for(var j = 0; j < beforeList.length; ++j) {
for(var item = befores[beforeList[j]]; item != null; item = item.next) {
if(!beforeSet[item.id]) {
beforeList.push(item.id);
beforeSet[item.id] = 1;
}
}
}
// for our comparison we don't care if id is in beforeSet
lookup[id] = beforeSet;
// slice beforeList to get only the elements after id here:
//beforeList = beforeList.slice(1, beforeList.length);
}
// Now sort using the following
// a) if rhs is present in "before"-set of lhs then lhs < rhs
// b) if rhs is not present then rhs < lhs
// c) there is information missing from our graph if a) and b) for lhs analogous lead to a different conclusion!
list.sort(function(lhs, rhs) {
if(!lhs.after || !rhs.before) return -1;
if(!lhs.before || !rhs.after) return 1;
if(lhs.id === rhs.id) return 0;
// different ids guaranteed, doesn't matter if lookup[id] contains id itself
var result = lookup[lhs.id][rhs.id] ? -1 : 1;
// expect reversing lhs and rhs to get inverse result
var expected = lookup[rhs.id][lhs.id] ? 1 : -1;
if(result != expected) {
// alert: there is no adjacency information between lhs and rhs!
}
return result;
});
list.sort(function(a, b) {
if (/* a before b, b after a */) {
return -1;
} else if (/* b before a, a after b */) {
return 1;
}
return 0;
});