# Rearrange a number into non-English alphabetical order in Raku

So there are a couple of things that I'd take a look at, but it does look like you're doing a few extra steps (in the comments you said you've tried a few different things, so I imagine you didn't initial do some many extra).

You've first given yourself the german numbers:

my @numDE = <null eins zwei drei vier fünf sechs sieben acht neun>;


Next, you want to be able to order things based on the German spelling. I'll try to use the method you've approached, but I'll show you a simplier way at the end. Your next step is to effectively cache the sort order of them, and store it into a variable "numrank". Building off of @numDE.sort.kv, we get

my %numrank;
for @numDE.sort.kv -> $k,$v {
%numrank{$v} =$k;
}
say %numrank;
# {acht => 0, drei => 1, eins => 2, fünf => 3, neun => 4, null => 5, sechs => 6, sieben => 7, vier => 8, zwei => 9}


Okay, not bad. Also note that while the output of %numrank appears to be ordered, as a hash, it is inherently unordered. It just happens to print keys in alphabetical as a rule and our keys and values are sorted on those lines. Now we just need to use the actual number as the key, rather than the German name instead.

my %numrank;
for @numDE.sort.kv -> $k,$v {
my $id == @numDE.first:$v;
%numrank{$id} =$k;
}
say %numrank;


Oops, we get the same thing. This is because .first returns the actually object. For its index, we just attach the :k adverb:

my %numrank;
for @numDE.sort.kv -> $k,$v {
my $id == @numDE.first:$v, :k;
%numrank{$id} =$k;
}
say %numrank;
# {0 => 5, 1 => 2, 2 => 9, 3 => 1, 4 => 8, 5 => 3, 6 => 6, 7 => 7, 8 => 0, 9 => 4}


Perfect, now we can see that the value for 8 (acht) is 0 as it's first, and for 2 (zwei) is 9, as it's last. Note that we could also have used an array here, since our indices are numbers (using @numrank and then doing @numrank[$id] =$k)

Now to sort some stuff. In your code you have

%temp{"$_"}= %numrank{"$_"} for "2378".comb; # 2378 sample input


This creates an unordered hash, wherein the name of each key is a digit, and its value is its rank. That's basically what we had above in the first attempt at making %numrank. But because %temp is a hash, if you have any two digits that repeat, you'll lose the extras:

%temp{"$_"}= %numrank{"$_"} for "222".comb;
# {2 => 9}


Instead, I think you want to create an array which can allow for ordering:

my @temp = ($_ => %numrank{"$_"}) for "22378".comb;
# ^^ both 2s are preserved


Now you can simply sort on the values:

say @temp.sort: *.values;


You could loop directly on this:

for @temp.sort(*.values) {
print .key;
}


## The simpler way

"2378".comb.sort: { @numDE[$^digit] } # (8 3 7 2) # acht drei seiben zwei  Here we sort the combed digits based on the German text form of each number. @numDE as the names of the numbers, and $^digit is an implicit variable that holds the digit (the [ ] automatically coerces it to a number for us). If you plan on using it regularly, you can actually store the block in a variable, like this:

my &sort-de = sub ($digit) { @numDE[$digit] };
"87446229".comb.sort: &sort-de;
# (8 9 6 7 4 4 2 2)


And as mentioned above, you can do the for loop directly on this, if you want to style it in some other manner:

for "87446229".comb.sort(&sort-de) {
say \$_
}