简体   繁体   中英

Javascript sort algorithm for linked sections objects array

I have the following array of objects which need to be sorted in a special way:

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

All sections are linked together via sectionA.end == sectionB.begin so the result of the sort operation should be:

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

I want to do this in the Array.prototype.sort() method. I realised that the beginning section could be found if the begin is not an end in any section but from there on I am lot. Has anybody an idea how to implement something like this?

I did a JSFiddle: https://jsfiddle.net/fxmnxh8L/1/

Try this:

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

EDIT: the above solution doesn't work (see comments to know why). Take a look at the below solution that use a recursive approach to compare two given 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); 

You can not sort the array with Array#sort , because you need to have a stable sorting with defined predecessor, item and successor, which is not given, only if you view at two elements.

So you need a different approach by chaining all parts and get then the result out of the parts.

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

try :

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/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM