用于链接节对象数组的Javascript排序算法

时间:2017-11-14 11:16:44

标签: javascript arrays algorithm sorting

我有以下对象数组需要以特殊方式排序:

var sections = [
    {begin:"test3", end:"test4"},
    {begin:"test5", end:"test2"},
    {begin:"test2", end:"test3"},
];

所有部分都通过sectionA.end == sectionB.begin链接在一起,因此排序操作的结果应为:

var sectionsSorted = [
    {begin:"test5", end:"test2"},
    {begin:"test2", end:"test3"},
    {begin:"test3", end:"test4"}
];

我想在Array.prototype.sort()方法中执行此操作。我意识到,如果begin在任何部分都不是end,那么就可以找到开始部分,但是从那里我很多。有人知道如何实现这样的事情吗?

我做了一个JSFiddle:https://jsfiddle.net/fxmnxh8L/1/

3 个答案:

答案 0 :(得分:3)

试试这个:

var sections = [
    {begin:"test3", end:"test4"},
    {begin:"test5", end:"test2"},
    {begin:"test2", end:"test3"},
];

sections.sort((s1, s2) => {
  return s1.end === s2.begin ? -1 : 1;
});

console.log(sections);

编辑:上述解决方案不起作用(请参阅注释以了解原因)。看一下使用递归方法比较两个给定部分的下面的解决方案:

var sections = [    
    {begin: "test4", end: "test7"},
    {begin: "test5", end: "test2"},
    {begin: "test7", end: "test8"},
    {begin: "test2", end: "test3"},
    {begin: "test3", end: "test4"},
    {begin: "test8", end: "test9"}
];

var sectionsMap = sections.reduce((m, o) => {
    m[o.begin] = o;
    return m;
}, {});

function compare(a, b) {
    if (!sectionsMap[a.end]) {
        return 1;
    } else if (sectionsMap[a.end].begin === b.begin) {
        return -1;
    } else {
        return compare(sectionsMap[a.end], b);
    }
}

sections.sort(compare);

console.log(sections);

答案 1 :(得分:1)

您无法使用Array#sort对数组进行排序,因为只有在以两个元素查看时才需要使用已定义的前导,项和后继进行稳定排序。

所以你需要通过链接所有部分来获得不同的方法,然后从部分中获得结果。



var sections = [{ begin: "test3", end: "test4" }, { begin: "test5", end: "test2" }, { begin: "test2", end: "test3" }],
    nodes = Object.create(null),
    begin = Object.create(null),
    end = Object.create(null),
    result;

sections.forEach(function (o) {
    nodes[o.begin] = o;
    begin[o.begin] = { a: [o.begin, o.end] };
    end[o.end] = begin[o.begin];

    if (begin[o.end]) {
        begin[o.end].a.unshift(o.begin);
        begin[o.begin] = begin[o.end];
        delete begin[o.end];
        delete end[o.end];
    }

    if (end[o.begin]) {
        Array.prototype.splice.apply(begin[o.begin].a, [0, 1].concat(end[o.begin].a));
        end[o.begin].a = begin[o.begin].a;
        delete begin[o.begin];
        delete end[o.end];
    }
    delete end[o.begin];
});

result = Object.keys(begin).map(function (k) {
    return begin[k].a.slice(0, -1).map(function (n) {
        return nodes[n];
    });
});

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 2 :(得分:0)

尝试:

function compare(a,b) {
 if (a.end < b.end)
    return -1;
 if (a.end > b.end)
    return 1;
      }

sections.sort(compare);

https://jsfiddle.net/Micio/Lu3wqt0v/1/