This sorts by prepending the file pathnames with the basename, sorting that numerically, and then stripping the basename from the front of the string:
#!/bin/bash
#
filearray=("dir1/0010.pdf" "dir2/0003.pdf" "dir3/0040.pdf" "dir4/0003.pdf")
sortarray=($(
for file in "${filearray[@]}"
do
echo "$file"
done |
sed -r 's!^(.*)/([[:digit:]]*)(.*)$!\2 \1/\2\3!' |
sort -t $'\t' -n |
sed -r 's![^ ]* !!'
))
for item in "${sortarray[@]}"
do
echo "> $item <"
done
It would be more efficient if you had the filenames in a list that could be passed directly through a pipe rather than as a shell array, because the actual work is done by the sed | sort | sed structure, but this suffices.
I first came across this technique when coding in Perl; in that language it was known as a Schwartzian Transform.
In Bash the transform as given here in my code will fail if you have non-numerics in the file's basename. In Perl it could be coded far more safely.