【问题标题】:Sort items by matching Start- and End Nodes通过匹配开始和结束节点对项目进行排序
【发布时间】:2017-11-30 15:36:28
【问题描述】:

假设我有一组随机打乱的碎片,属于不同的组。例如:

let pieces = [
  {
    id: "a1",
    startNode: 18,
    endNode: 42,
  },
  {
    id: "a3",
    startNode: 16,
    endNode: 30,
  },
  {
    id: "b2",
    startNode: 48,
    endNode: 65,
  },
  {
    id: "a2",
    startNode: 42,
    endNode: 16,
  },
  {
    id: "a4",
    startNode: 30,
    endNode: 31,
  },
  {
    id: "b1",
    startNode: 23,
    endNode: 48,
  },
];

我希望它们以正确的顺序作为两个数组返回:

ordered = [
  [
    {
      id: "a1",
      startNode: 18,
      endNode: 42,
    },
    {
      id: "a2",
      startNode: 42,
      endNode: 16,
    },
    {
      id: "a3",
      startNode: 16,
      endNode: 30,
    },
    {
      id: "a4",
      startNode: 30,
      endNode: 31,
    },
  ],[
    {
      id: "b1",
      startNode: 23,
      endNode: 48,
    },
    {
      id: "b2",
      startNode: 48,
      endNode: 65,
    },
  ]
];

它们按匹配的开始和结束节点排序,因此“a2”排在“a1”之后,因为它的 startNode 与“a1”的 endNode 匹配。 “b1”和“b2”属于不同的组,因为它们不与任何“a”组共享起始节点或结束节点。 id 不能用于排序,这里只是为了清楚起见。

关于如何做到这一点的任何想法?我认为它需要某种递归函数,但我无法完全理解。

【问题讨论】:

    标签: javascript sorting


    【解决方案1】:

    您可以使用迭代方法,同时针对实际(外部)元素迭代子结果。

    这个单个元素将所有匹配的开始和结束节点收集到一个数组中,而其他不匹配的节点将被过滤,然后将收集数组连接起来。

    var pieces = [{ id: "a1", startNode: 18, endNode: 42 }, { id: "a3", startNode: 16, endNode: 30 }, { id: "b2", startNode: 48, endNode: 65 }, { id: "a2", startNode: 42, endNode: 16 }, { id: "a4", startNode: 30, endNode: 31 }, { id: "b1", startNode: 23, endNode: 48 }],
        result = pieces.reduce(function (r, a) {
            var temp = [a];
            return r.filter(function (b) {
                if (temp[temp.length - 1].endNode === b[0].startNode) {
                    temp = temp.concat(b);
                    return;
                }
                if (temp[0].startNode === b[b.length - 1].endNode) {
                    temp = b.concat(temp);
                    return;
                }
                return true;
            }).concat([temp]);
        }, []);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 哇,尼娜,这真的很成功。我也用更多的数据尝试过它,它就像一个魅力。现在我需要仔细看看你用过滤器功能做了什么。不胜感激。
    【解决方案2】:

    尝试简单的Array#sort() =>a.id > b.id

    let pieces = [ { id: "a1", startNode: 18, endNode: 42, }, { id: "a3", startNode: 16, endNode: 30, }, { id: "b2", startNode: 48, endNode: 65, }, { id: "a2", startNode: 42, endNode: 16, }, { id: "a4", startNode: 30, endNode: 31, }, { id: "b1", startNode: 23, endNode: 48, }, ];
    
    console.log(pieces.sort((a,b)=> a.id > b.id))

    不支持的箭头函数=>ES5

    一起使用
       console.log(
        pieces.sort(function(a,b){
        return a.id > b.id})
        )
    

    【讨论】:

    • 即使这适用于测试用例,我认为排序应该是 startNode == previous endNode
    • 对不起,id 和 node 值实际上是一些任意的 9 位数字序列。为了便于阅读,我在这里修改了它们。它们不能用于排序,只能用于节点值。
    猜你喜欢
    • 2021-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 2023-03-19
    • 2014-04-21
    相关资源
    最近更新 更多