Sort items by matching start and end nodes

Let's say I have an array of random shuffles belonging to different groups. For example:

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

      

I want to return them as two arrays in the correct order:

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

      

They are sorted by their matching start and end nodes, so "a2" comes after "a1" because its startNode matches "end1ode" a1. "b1" and "b2" belong to a different group, since they do not share the start or end node with any of the "a" groups. The id cannot be used for sorting, it's just for clarity here.

Any ideas on how to do this? I think it needs some kind of recursive function for this and I cannot fully understand it.

+3


source to share


2 answers


You can use an iterative approach, while iterating over sub-selections and against the actual (outer) element.

This single element collects all matching start and end nodes in an array, while other non-matching nodes are filtered and then combined with the collection array.



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

Run code


+2


source


Try with simple 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))
      

Run code




Unsupported arrow function =>

used with ES5

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

      

+2


source







All Articles