Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.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_Arrays_Algorithm_Sorting_Object - Fatal编程技术网

在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

(如果您愿意,可以缩短该块,但要牺牲可读性。)

部分回答,太长,无法发表评论。你可能已经明白了,我只是希望它能帮助别人找到解决办法

  • 解决方案可能是不可能的,也可能是众多方案之一
  • 如果在“之前”或“之后”遍历中存在定向循环,则没有解决方案(@BeyelerStudios’credit)
  • 第一个没有“后”,最后一个没有“前”
  • 第二个必须在“之后”中有第一个id,可以设置
  • 集合可以递归排序
  • 如何确定剩余元素的位置,我想不出来
  • 此函数在就地排序:在数组中移动项目时非常有用:

    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;
    });