javascript - How to sort an array with sometimes incomparable values? -
i trying sort values incomparable each other. data sorting resembles tree
1. if depends on b, should sorted after b 2. if b depends on a, b should sorted after 3. if neither or b depend on each other incomparable , no comparison can drawn
i using sort function in javascript custom compare function. suspect not appropriate require topological sorting
example code tests:
// k depends on nothing - every other element depends on k, k should come first var k = { uuid: 'k', dependson: [] }; // z depends on k , k must come before z var z = { uuid: 'z', dependson: ['k'] } // y should go before x x depends on y // y depends on k k should go before y var y = { uuid: 'y', dependson: ['k'] } // x has both y , k dependencies var x = { uuid: 'x', dependson: ['y', 'k'] } function compare(a, b) { // if have same uuid; same if (a.uuid === b.uuid) { return 0 } // if depends on b, should after b (var = 0, len = a.dependson.length; < len; i++) { var dependson = a.dependson[i]; if (dependson === b.uuid) { return 1 } } // if b depends on a, b should after (var = 0, len = b.dependson.length; < len; i++) { var dependson = b.dependson[i]; if (dependson === a.uuid) { return -1 } } // edge case, // if neither or b depends on each other, don't have relative ranking return null } // every possible permutation - should sort same orders // expected order k, z, y, x or k, y, z, x or k, y, x, z // because: // k -> z z depends on k // k -> y y depends on k // no relative ranking between z , y don't depend on each other // x depends on both y , k x come after them var perms = [ [x, y, z, k], [x, y, k, z], [x, z, y, k], [x, z, k, y], [x, k, y, z], [x, k, z, y], [y, x, z, k], [y, x, k, z], [y, z, x, k], [y, z, k, x], [y, k, x, z], [y, k, z, x], [z, x, y, k], [z, x, k, y], [z, y, x, k], [z, y, k, x], [z, k, x, y], [z, k, y, x], [k, x, y, z], [k, x, z, y], [k, y, x, z], [k, y, z, x], [k, z, x, y], [k, z, y, x], ] var _ = require('underscore') perms.foreach(function(perm) { var s = perm.sort(compare) var p = _.pluck(s, 'uuid') console.log(p, _.isequal(p, ['k', 'z', 'y', 'x']) || _.isequal(p, ['k', 'y', 'z', 'x']) || _.isequal(p, ['k', 'y', 'x', 'z'])) })
example output (with annotation):
[ 'k', 'y', 'x', 'z' ] true [ 'k', 'y', 'x', 'z' ] true [ 'k', 'x', 'z', 'y' ] false \\ x depends on k , y should after y [ 'k', 'x', 'z', 'y' ] false [ 'k', 'y', 'x', 'z' ] true [ 'k', 'x', 'z', 'y' ] false \\ x depends on k , y should after y [ 'k', 'y', 'x', 'z' ] true [ 'k', 'y', 'x', 'z' ] true [ 'k', 'y', 'z', 'x' ] true [ 'k', 'y', 'z', 'x' ] true [ 'k', 'y', 'x', 'z' ] true [ 'k', 'y', 'z', 'x' ] true [ 'k', 'z', 'y', 'x' ] true [ 'k', 'z', 'y', 'x' ] true [ 'k', 'z', 'y', 'x' ] true [ 'k', 'z', 'y', 'x' ] true [ 'k', 'z', 'y', 'x' ] true [ 'k', 'z', 'y', 'x' ] true [ 'k', 'y', 'x', 'z' ] true [ 'k', 'x', 'z', 'y' ] false \\ x depends on k , y should after y [ 'k', 'y', 'x', 'z' ] true [ 'k', 'y', 'z', 'x' ] true [ 'k', 'z', 'y', 'x' ] true [ 'k', 'z', 'y', 'x' ] true
i found seemingly not actively maintained library did job:
// k depends on nothing - every other element depends on k, k should come first var k = { uuid: 'k', dependson: [] }; // z depends on k , k must come before z var z = { uuid: 'z', dependson: ['k'] } // y should go before x x depends on y // y depends on k k should go before y var y = { uuid: 'y', dependson: ['k'] } // x has both y , k dependencies var x = { uuid: 'x', dependson: ['y', 'k'] }; function edges(array) { var edges = [] (var k in array) { var node = array[k] node.dependson.foreach(function(dependency) { edges.push([dependency].concat(node.uuid)) }) } return edges } // every possible permutation - should sort same orders // expected order k, z, y, x or k, y, z, x or k, y, x, z // because: // k -> z z depends on k // k -> y y depends on k // no relative ranking between z , y don't depend on each other // x depends on both y , k x come after them var perms = [ [x, y, z, k], [x, y, k, z], [x, z, y, k], [x, z, k, y], [x, k, y, z], [x, k, z, y], [y, x, z, k], [y, x, k, z], [y, z, x, k], [y, z, k, x], [y, k, x, z], [y, k, z, x], [z, x, y, k], [z, x, k, y], [z, y, x, k], [z, y, k, x], [z, k, x, y], [z, k, y, x], [k, x, y, z], [k, x, z, y], [k, y, x, z], [k, y, z, x], [k, z, x, y], [k, z, y, x], ] var _ = require('underscore') var toposort = require('toposort') perms.foreach(function(perm) { var p = toposort(edges(perm)); console.log(p, _.isequal(p, ['k', 'z', 'y', 'x']) || _.isequal(p, ['k', 'y', 'z', 'x']) || _.isequal(p, ['k', 'y', 'x', 'z'])) })
Comments
Post a Comment