Consider the following array of objects:
[
{v: 'a'},
{v: 'b'},
{v: 'c', ptr: 'b'},
{v: 'd', ptr: 'a'},
{v: 'e'},
]
Some of the objects contain a ptr
property, referencing the v
property value of an object that it should directly preceed. Two objects will never attempt to directly preceed the same object, and there will never be a loop (e.g. a->b->c->a) in the array.
Therefore, here are two possible valid rearrangements of the objects:
[
{v: 'e'},
{v: 'd', ptr: 'a'},
{v: 'a'},
{v: 'c', ptr: 'b'},
{v: 'b'},
]
[
{v: 'c', ptr: 'b'},
{v: 'b'},
{v: 'd', ptr: 'a'},
{v: 'a'},
{v: 'e'}
]
It doesn’t matter at all where objects appear in the output, if there is no ptr
property referencing it. All that matters is that certain objects directly preceed others where the ptr
property requests it.
What is a reasonably efficient algorithm to perform this kind of rearrangement?
Although the data is guaranteed to not contain loops, the rearrangement should be careful not to get into an infinite loop where it keeps rearranging the objects forever.
Note that although these examples use strings for v
and ptr
, the actual application will involve DOM elements as the values for v
and ptr
references. Therefore, the solution should only be able to compare v
and ptr
properties for equality.
3
Answers
Figure out which objects have another object pointing to them. Then, for each object that doesn’t have another object pointing to it, add that object and everything in the following ptr chain to the output:
I know this has been answered but I still want to post mine :p
Added a few more chains for testing as well. The root of each chain is where the resulting chain will stem, so even though the chain starting at c is defined before the unchained g, the last element i is the root of chain c, thus its entire chain is positioned there.
I think this is straightforward to do with
sort
. Put items with aptr
property matching the other item’sv
property in order. If theptr
properties both exist, just compare them normally.Output: