Sorting a list of things in "(decide which number is)" order

Following up on this question, I realized I had one of my own.

I have a case where I want to list things to track in order of relevance. But I feel like I’m taking two steps when I should take one.

a sort-thing is a kind of thing. a sort-thing has a number called temp-sort-order.

p1 is a sort-thing.
p2 is a sort-thing.
p3 is a sort-thing.
p4 is a sort-thing.

to decide which number is sort-order-defined of (th - a sort-thing):
	if th is p1, decide on 1;
	if th is p2, decide on 2;
	if th is p3, decide on 3;
	if th is p4, decide on 4;
	decide on 0;

when play begins: [ this is just a check to make sure sord is sorted to p1, p2, p3, p4 ]
	let sord be { p3, p1, p4, p2 };
	say "[sord].";
	repeat with x running through sort-things:
		now temp-sort-order of x is sort-order-defined of x;
	sort sord in temp-sort-order order;
	say "[sord].";

I’m wondering if I’m missing a way to say sort sord in sort-order-defined order that compiles. But this doesn’t happen–at least, in 6L or 6G, it doesn’t. The solution I have is adequate, but if it could be more succinct, great!

Thanks!

1 Like

As mentioned in the post that you linked, it’s possible to sort a list by a property of the objects in it; see WWI 21.8 Sorting, reversing and rotating lists. You can’t sort on a computed property (though that would be nice), only a property that holds a value.

Is there a specific context in which you want to show things in a sorted order, or is this a generic effect that you’re trying to get?

1 Like

Let’s create it:

Step by step

First we create the I7 sort L in (phrase) order and sort L in reverse (phrase) order.
This is directly inspired by the existing code.

To sort (L - a list of objects) in/into (ph - phrase sort-thing -> number) order:
	(- LIST_OF_TY_SortBy({-lvalue-by-reference:L}, 1, {ph}); -).

To sort (L - a list of objects) in/into reverse (ph - phrase sort-thing -> number) order:
	(- LIST_OF_TY_SortBy({-lvalue-by-reference:L}, -1, {ph}); -).

Then, we need to provide LIST_OF_TY_SortBy :
This is a simplified version of LIST_OF_TY_Sort. All it does is to tell the sorting algorithm to use our ListCompareEntriesBy function.

[ LIST_OF_TY_SortBy list dir phrase no_items;
	BlkMakeMutable(list);
	no_items = BlkValueRead(list, LIST_LENGTH_F);
	SetSortDomain(ListSwapEntries, ListCompareEntriesBy);
	SortArray(list, phrase, dir, no_items, false, 0);
];

Then ListCompareEntriesBy:
This is a simplified version of ListCompareEntries . All it does is invoke the I7 phrase to get the computed value.

[ ListCompareEntriesBy list phrase i j;
	if (i==j) return 0;
	i = BlkValueRead(list, LIST_ITEM_BASE+i-1);
	j = BlkValueRead(list, LIST_ITEM_BASE+j-1);
	i = (phrase-->1)(i);
	j = (phrase-->1)(j);
	if (i > j) return 1;
	if (i < j) return -1;
	return 0;
];

Full example

a sort-thing is a kind of thing.

p1 is a sort-thing. 
p2 is a sort-thing. 
p3 is a sort-thing. 
p4 is a sort-thing. 

to decide which number is sort-order-defined of (th - a sort-thing) (this is simple sort):
	if th is p1, decide on 1;
	if th is p2, decide on 2;
	if th is p3, decide on 3;
	if th is p4, decide on 4;
	decide on 0;

to decide which number is sort-order-defined of (th - a sort-thing) (this is weird sort):
	if th is p1, decide on 13;
	if th is p2, decide on -5;
	if th is p3, decide on 22;
	if th is p4, decide on 4;
	decide on 0;

when play begins:
	let sord be { p3, p1, p4, p2 };
	say "[sord].";
	sort sord in simple sort order;
	say "[sord].";
	sort sord in reverse simple sort order;
	say "[sord].";
	sort sord in weird sort order;
	say "[sord].";
	
	
Lab is a room.

To sort (L - a list of objects) in/into (ph - phrase sort-thing -> number) order:
	(- LIST_OF_TY_SortBy({-lvalue-by-reference:L}, 1, {ph}); -).

To sort (L - a list of objects) in/into reverse (ph - phrase sort-thing -> number) order:
	(- LIST_OF_TY_SortBy({-lvalue-by-reference:L}, -1, {ph}); -).

Include (-

[ LIST_OF_TY_SortBy list dir phrase no_items;
	BlkMakeMutable(list);
	no_items = BlkValueRead(list, LIST_LENGTH_F);
	SetSortDomain(ListSwapEntries, ListCompareEntriesBy);
	SortArray(list, phrase, dir, no_items, false, 0);
];

[ ListCompareEntriesBy list phrase i j;
	if (i==j) return 0;
	i = BlkValueRead(list, LIST_ITEM_BASE+i-1);
	j = BlkValueRead(list, LIST_ITEM_BASE+j-1);
	i = (phrase-->1)(i);
	j = (phrase-->1)(j);
	if (i > j) return 1;
	if (i < j) return -1;
	return 0;
];

-)

3 Likes