Transferring item rearrangement on a new array?

Hello all,

can the moving of elements of an array be applied onto another array?
e.g.;

a=[ 8, 1, 3, 5, 7, 6, 6, 2 ]
a.sort
a=[ 1, 2, 3, 5, 6, 6, 7, 8 ]

now trying to apply the rearrangement of these items on new array of the same length?
Thanks,
jan

Is the fact that element 6 appears twice on purpose? If so, the following might not work.

(
var elements = ["a", "b", "c", "d"].debug("elements");
var ordering = [1,4,2,3].debug("ordering");
var decorated = [ordering,elements].lace.clump(2).debug("decorated");
var sorted = decorated.sort({|a,b| a[0] < b[0] }).debug("sorted");
var undecorated = decorated.collect({ | el | el[1] }).debug("undecorated");
)

output

elements: [ a, b, c, d ]
ordering: [ 1, 4, 2, 3 ]
decorated: [ [ 1, a ], [ 4, b ], [ 2, c ], [ 3, d ] ]
sorted: [ [ 1, a ], [ 2, c ], [ 3, d ], [ 4, b ] ]
undecorated: [ a, c, d, b ]
-> nil
1 Like

And an alternative that would work with repeated numbers as well

(
var elements = ["a", "b", "c", "d"].debug("elements");
var ordering = [1,4,3,2,3].debug("ordering");
var resorted = ordering.collect({ | o | elements[o-1] }).debug("resorted"); // o-1 because the ordering is one-based, and indexing is zero-based
)

output

elements: [ a, b, c, d ]
ordering: [ 1, 4, 3, 2, 3 ]
resorted: [ a, d, c, b, c ]
-> nil

Yes, it was just a random array.
The alternative option looks like it will do it! Another thing learned, thank you!

Incidentally there is an order method that will give you the indices to produce a sorted array – it’s a bit hard to explain in one sentence. The help file example might illustrate it better.

hjh

hm, im still somewhat confused about the proposed example with debug. in an attempt for more clarity:

if i have a first array a = [9,1,7,3]
that gets sorted a.sort = [1,3,7,9]

which means items got rearranged, e.g. item “9” moved from slot 1 to 4, “3” from slot 4 to 2, etc.
i want to apply the same rearrangement of items on a second array:

b = [2,8,6,4]
which should, result in this: [8,4,6,2]

the alternative example presupposes that the item reordering pattern is known (“ordering”), but at least to me its not obvious exactly how (function of debug?), as it only happens implicitely in a.sort.

@jamshark70 this knowledge of the rearrangement pattern would probably also be necessary for the order method, as far as i understand?

thanks,
jan

the method .debug just prints the contents of a variable to the post window with a user defined prefix

I had assumed that your “ordering” array was an array of increasing numbers, used only to determine the reordering of elements. But apparently this is not what you want.

Using the .order method (which is less typing work than the decorate-undecorate method)

(
var elements = ["nora", "andre", "nel", "ipsy", "liam"].debug("elements");
var other_array = [100, 200, 300, 400, 500].debug("other_array");
var elements_order = elements.order({ |a, b| a < b }).debug("elements_order");
var elements_sorted = elements.sort({ |a, b| a < b }).debug("elements_sorted");
var other_array_resorted = elements_order.collect({|el| other_array[el] }).debug("other_array_resorted");
)

output

elements: [ nora, andre, nel, ipsy, liam ]
other_array: [ 100, 200, 300, 400, 500 ]
elements_order: [ 1, 3, 4, 2, 0 ]
elements_sorted: [ andre, ipsy, liam, nel, nora ]
other_array_resorted: [ 200, 400, 500, 300, 100 ]
-> nil
1 Like

My main suggestion here would be to try the method and look at the output, rather than guessing.

I’m not at the computer now, but I believe that you’d get this:

a = [9, 1, 7, 3];

i = a.order;
-> [1, 3, 2, 0]  // i.e. a[1] is the lowest, a[3] is second lowest, etc

a[i]
-> [1, 3, 7, 9];

b = [2, 8, 6, 4];

b[i]
-> [8, 4, 6, 2];

… which is exactly what you wanted!

hjh

1 Like

This is it indeed, thank you @shiihs!

Also really elegant solution, thank you!
(I did try it, mistakenly on the Order class instead of method, which seemed to me to require precisely the indices information)