Classificando uma matriz com base na substring de cada elemento

Classificando uma matriz com base na substring de cada elemento

Como classificar um array com base em uma substring de cada elemento?
por exemplo, dado um array como

arr=( 2some05stuff 4more02stuff 3evenmore01stuff 1no04stuff )

Eu gostaria de classificar os elementos pela sequência numérica que precede, stuffpara terminar com

3evenmore01stuff
4more02stuff
1no04stuff
2some05stuff

Eu sei que a expansão de parâmetros sinaliza o/ Oreordena uma matriz, por exemplo

imprimir -rl "${(@on)arr}"
1no04stuff
2some05stuff
3evenmore01stuff
4more02stuff

e

imprimir -rl "${(@On)arr}"
4more02stuff
3evenmore01stuff
2some05stuff
1no04stuff

Só não sei se é possível combiná-los com uma função ou outra expansão de parâmetro, como, por exemplo, remoção de subscrito ou expansão de subscrito...

Responder1

Não conheço uma maneira de fazer isso inline. Com qualificadores globs, você pode especificar uma chave de classificação ( *(oe\''REPLY=${${REPLY%stuff*}##*[^0-9]}'\')), mas isso não existe com modificadores de expansão de parâmetro.

O que você pode fazer é construir um array auxiliar contendo ${sort_key}$'\0'${value}, ou seja, anexar um byte nulo e o valor original à chave de classificação. Supondo que as chaves de classificação não contenham bytes nulos, a classificação dessa matriz fornece a ordem desejada e a remoção do prefixo da chave de classificação fornece o resultado desejado.

typeset -a tmp; tmp=(); typeset -i i
for ((i=1; i<=$#arr; i++)); do tmp[$i]=${${arr[$i]%stuff*}##*[^0-9]}$'\0'$arr[$i]; done
print -lr "${(@)${(@o)tmp}#*$'\0'}"

informação relacionada