【问题标题】:Sorting hierarchical data in Javascript (Adjacency List/Flat table)在 Javascript 中对分层数据进行排序(邻接表/平面表)
【发布时间】:2012-07-01 12:40:25
【问题描述】:

我正在尝试对以下数据进行排序:

var data = [
    { path: '/a', order: 0 },
    { path: '/b', order: 1 },
    { path: '/a/d', order: 1 },
    { path: '/a/c', order: 0 }
];

进入:

var expected = [
    { path: '/a', order: 0 },
    { path: '/a/c', order: 0 },
    { path: '/a/d', order: 1 },
    { path: '/b', order: 1 }
];

我发现了一篇关于分层数据的好帖子:

What are the options for storing hierarchical data in a relational database?

从那个问题来看,我认为我使用的是平板:

对邻接列表的修改,为每条记录添加一个级别和排名(例如排序)列。

该 SO 问题中的链接已关闭,因此我无法从中获得更多信息。

我设置了一个 JsFiddle 来断言我的排序功能:

http://jsfiddle.net/U76ch/

我已经尝试了一些方法,但都没有给出正确的结果。

一个完全不同的解决方案是添加顺序并按字母顺序排序。但是由于结果最终会以 url 形式出现,所以拥有 www.example.com/01-products/01-snowboard 有点难看。

更新

我创建了一个更复杂的 JSFiddle 示例来展示我想要做什么:

http://jsfiddle.net/YSd3d/

所以我尝试按路径排序,但节点应按其级别的顺序排序。因此,就像文件系统一样,您按字母顺序排序,但最后一个子项按顺序排序。

【问题讨论】:

  • 对于更新后的示例:/cars/bikes 是路径 / 中的节点 carsbikes,两者都必须位于开头。
  • 难道不能按照我预期的方式对它们进行排序吗?我想要 /parent, /parent/child, /parent, /parent/child 取决于他们的订单价值。
  • 不使用排序功能,因为如果你有两个随机元素,你不得不说第一个是更低、更高或相等而不使用/知道其他元素。但是例如如果您有元素 /bikes/some-brand/cars/bmw,则结果取决于元素 /cars/bikes

标签: javascript hierarchical-data


【解决方案1】:
var data = [
    { path: '/a', order: 0 },
    { path: '/b', order: 1 },
    { path: '/a/d', order: 1 },
    { path: '/a/c', order: 0 }
];

data.sort(function(a, b) {
  if (a.path === b.path) {
    return a.order < b.order ? -1 : 1;
  } else {
    return a.path < b.path ? -1 : 1;
  };
});

【讨论】:

    【解决方案2】:

    你能对它做一个简单的排序吗?我不完全理解您在最后一段中的担忧。

    var result = data.sort(function (a, b) {
      return a.path > b.path;
    });
    

    http://jsfiddle.net/sftdq/


    编辑。我将您的测试更改为显示 order > abc。工作于jsfiddle exmample

    var data = [
        { path: '/a', order: 0 },
        { path: '/b', order: 1 },
        { path: '/a/a', order: 1 },
        { path: '/a/c', order: 0 }
    ];
    
    
    var result = data.sort(function (a, b) {
        if( a.order === b.order ){
            return a.path > b.path;
        }
        else {
            return a.order > b.order;
        }
    });
    
    
    var expected = [
        { path: '/a', order: 0 },
        { path: '/a/c', order: 0 },
        { path: '/a/a', order: 1 },
        { path: '/b', order: 1 }
    ];
    
    
    if (_.isEqual(result, expected)) {
        alert('Success');       
    } else {
        alert('Failed');  
    };
    ​
    

    【讨论】:

    • 如果您有 /products/a-snowboard 和 /products/b-snowboard,我可能希望 b-snowboard 先于 a-snowboard。
    • 啊,所以你想先按order 排序,然后按字母顺序?尽管order,您的示例仍按字母顺序排序,这就是我认为我错过它的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    相关资源
    最近更新 更多