[Question]
  [
**Input:**
* An array containing three integers: `0`, `1` and `2` in any order (i.e. `[2, 0, 1]`)
* And a string of length >= 2 only containing alphabetic letters (both lower- and uppercase) and digits (i.e. `a1B2c3`)
**Output:**
Based on the array we sort and output the string.  
How does this work?
* The array indicates the order precedence of `a-z`, `A-Z` and `0-9`, the first being `0`; second being `1`; and third being `2`.
* The individual characters of the string can then be ordered based on that.
**Example:**
* Array: `[2, 0, 1]`
* String: `a1B2c3`
Based on the array, we know our order precedence is `0-9a-zA-Z`.  
Based on that, we can convert and output the string: `123acB`.
**Challenge rules:**
* For the array you can choose to use 0-indexed or 1-indexed input, so `[3, 1, 2]` is also a valid input if you prefer to use 1-indexed arrays.
* The string (both input and output) only contains valid characters: `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`.
* If your language doesn't support arrays (or if you choose to), you are free to use strings instead of arrays for the first parameter (i.e. `012`, `[0,1,2]`, etc.).
**General rules:**
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so shortest answer in bytes wins.  
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
* [Standard rules apply](https://codegolf.meta.stackexchange.com/questions/2419/default-for-code-golf-program-function-or-snippet/2422#2422) for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
* [Default Loopholes](https://codegolf.meta.stackexchange.com/questions/1061/loopholes-that-are-forbidden-by-default) are forbidden.
* If possible, please add a link with a test for your code.
* Also, please add an explanation if necessary.
**Test cases:**
```
[2, 0, 1]  &  a1B2c3             ->   123acB
[2, 1, 0]  &  aAaA909UuHWw9gh2   ->   02999AAHUWaaghuw
[2, 1, 0]  &  6Bx43              ->   346Bx
[1, 0, 2]  &  jfjf33g            ->   ffgjj33
[0, 2, 1]  &  AbC13              ->   b13AC
[1, 2, 0]  &  Qfl0l              ->   Q0fll
[0, 1, 2]  &  9870abcABC         ->   abcABC0789
[0, 2, 1]  &  test123            ->   estt123
[2, 0, 1]  &  WHAT               ->   AHTW
[2, 0, 1]  &  WhAt               ->   htAW
[1, 0, 2]  &  102BACbac          ->   ABCabc012
```
  
[Answer]
# Python 2, ~~67~~ 66 bytes
```
lambda s,k:`sorted(s,key=lambda c:`k.index(3-ord(c)/32)`+c)`[2::5]
```
Test it on [Ideone](http://ideone.com/TsKRBZ).
[Answer]
## JavaScript (ES6), 87 bytes
```
(a,s)=>a.map(n=>[...s].sort().join``.replace([/[^a-z]/g,/[^A-Z]/g,/\D/g][n],``)).join``
```
If the input array gave the order, rather than the precedence, of the three ranges (this only makes a difference for `[1, 2, 0]` and `[2, 1, 0]` whose effects are swapped) then this would have worked for 80 bytes:
```
(a,s,o=c=>a[(c<'a')+(c<'A')])=>[...s].sort((a,b)=>o(a)-o(b)||(a>b)-(a<b)).join``
```
I misread the question and still got 7 upvotes with this. Feel free to remove your upvotes and give them to @CharlieWynn instead, who came up with the best correction to my approach.
```
(a,s)=>a.map(n=>s.replace([/[^a-z]/g,/[^A-Z]/g,/\D/g][n],``)).join``
```
[Answer]
# [05AB1E](http://github.com/Adriandmen/05AB1E), ~~15~~ ~~14~~ 12 bytes
Code:
```
v²žK26ôyèÃ{?
```
Explanation:
```
v             # For each in the input array.
  žK          #   Push a-zA-Z0-9.
    26ô       #   Split into pieces of 26.
       yè     #   Get the element-th element of the array.
 ²       Ã    #   Keep the characters of that element from the second input.
          {?  #   Sort pop and print without a newline.
```
Uses the **CP-1252** encoding. [Try it online!](http://05ab1e.tryitonline.net/#code=dsKyxb5LMjbDtHnDqMODez8&input=WzIsIDEsIDBdCmFBYUE5MDlVdUhXdzlnaDI).
[Answer]
# [Jelly](http://github.com/DennisMitchell/jelly), 13 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
2_ịØWs26¤Ff@€
```
[Try it online!](http://jelly.tryitonline.net/#code=Ml_hu4vDmFdzMjbCpEZmQOKCrA&input=&args=WzIsIDAsIDFd+ImExQjJjMyI) or [verify all test cases](http://jelly.tryitonline.net/#code=Ml_hu4vDmFdzMjbCpEZmQOKCrArDpyJq4oG3&input=&args=WzIsIDAsIDFdLCBbMiwgMSwgMF0sIFsyLCAxLCAwXSwgWzEsIDAsIDJdLCBbMCwgMiwgMV0sIFsxLCAyLCAwXSwgWzAsIDEsIDJdLCBbMCwgMiwgMV0sIFsyLCAwLCAxXSwgWzIsIDAsIDFdLCBbMSwgMCwgMl0+ImExQjJjMyIsICJhQWFBOTA5VXVIV3c5Z2gyIiwgIjZCeDQzIiwgImpmamYzM2ciLCAiQWJDMTMiLCAiUWZsMGwiLCAiOTg3MGFiY0FCQyIsICJ0ZXN0MTIzIiwgIldIQVQiLCAiV2hBdCIsICIxMDJCQUNiYWMi).
### How it works
```
2_ịØWs26¤Ff@€  Main link. Arguments: k (permutation of [0, 1, 2]), s (string)
2_             Subtract the integers in k from 2, mapping [0, 1, 2] -> [2, 1, 0].
        ¤      Combine the three links to the left into a niladic chain.
   ØW          Yield the string following string.
               'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_'
     s26       Split it into chunks of 26 chars, i.e., ['A...Z', 'a...z', '0...9'].
  ị            Retrieve the chunks from the right result at the indices of the
               left result. The indices of the chunks are modular and 1-based;
               1 retrieves 'A...Z', 2 retrieves 'a...z', and 3 retrieves '0...9'.
         F     Flatten the resulting array of strings.
          f@€  Filter (swapped, each); for each character in the constructed
               string, select all occurrences of that character from s.
```
[Answer]
## Pyth, ~~17~~ ~~16~~ 15 bytes
```
s@RSz@L[GrG1`UT
```
[Test suite.](https://pyth.herokuapp.com/?code=s%40RSz%40L%5BGrG1%60UT&test_suite=1&test_suite_input=%5B2%2C+0%2C+1%5D%0Aa1B2c3%0A%5B2%2C+1%2C+0%5D%0AaAaA909UuHWw9gh2%0A%5B2%2C+1%2C+0%5D%0A6Bx43%0A%5B1%2C+0%2C+2%5D%0Ajfjf33g%0A%5B0%2C+2%2C+1%5D%0AAbC13%0A%5B1%2C+2%2C+0%5D%0AQfl0l%0A%5B0%2C+1%2C+2%5D%0A9870abcABC%0A%5B0%2C+2%2C+1%5D%0Atest123%0A%5B2%2C+0%2C+1%5D%0AWHAT%0A%5B2%2C+0%2C+1%5D%0AWhAt%0A%5B1%2C+0%2C+2%5D%0A102BACbac&debug=0&input_size=2)
```
       [          array literal containing...
        G           the alphabet (lowercase)
         rG1        the alphabet, converted to uppercase
            `UT     inspect-range-10, generating the range [0,10) and
                      stringifying it, resulting in a string that contains no
                      letters and all numbers (so equivalent to '0123456789' for
                      filtering)
                    this creates ['ab...z', 'AB...Z', '01...9']
     @L           map over first (implicit) input (the ordering array) and take
                   the nth element in this array for each item
                   this gives us ['01...9', 'ab...z', 'AB...Z']
   Sz             take another line of input as a string and sort it, and then...
 @R               map over intersection: filter the line of input over presence
                    in each element in the new array
                    this results in ['123', 'ac', 'B']
s                 concatenate all and implicitly output
```
Thanks to [@FryAmTheEggman](https://codegolf.stackexchange.com/users/31625/fryamtheeggman) for a byte and [@Jakube](https://codegolf.stackexchange.com/users/29577/jakube) for another!
[Answer]
# Javascript es6 77 bytes
```
(a,s)=>a.map(o=>s.match([/[a-z]?/g,/[A-Z]?/g,/\d?/g][o]).sort().join``).join``
```
---
```
//test
f=(a,s)=>a.map(o=>(s.match([/[a-z]/g,/[A-Z]/g,/\d/g][o])||[]).sort().join``).join``
f([2, 0, 1], "a1B2c3")             == "123acB" &&
f([2, 1, 0], "aAaA909UuHWw9gh2")   == "02999AAHUWaaghuw" &&
f([2, 1, 0], "6Bx43")              == "346Bx" &&
f([1, 0, 2], "jfjf33g")            == "ffgjj33" &&
f([0, 2, 1], "AbC13")              == "b13AC" &&
f([1, 2, 0], "Qfl0l")              == "Q0fll" &&
f([0, 1, 2], "9870abcABC")         == "abcABC0789" &&
f([0, 2, 1], "test123")            == "estt123" &&
f([2, 0, 1], "WHAT")               == "AHTW" &&
f([2, 0, 1], "WhAt")               == "htAW" &&
f([1, 0, 2], "102BACbac")          == "ABCabc012"
```
[Answer]
# TSQL, ~~199~~ 191 bytes
**Golfed:**
```
DECLARE @i varchar(99)='abA7B34',@s char(3)='213'
,@ varchar(99)=''SELECT @+=n FROM(SELECT top 99n FROM(SELECT top 99substring(@i,row_number()over(order by 1/0),1)n FROM sys.messages)c ORDER BY CHARINDEX(CHAR(ascii(n)/32+48),@s),n)d SELECT @
```
**Ungolfed:**
```
DECLARE @i varchar(99)='abA7B34'
-- 1 numbers, 2 upper case, 3 lower case
DECLARE @s char(3)='213'
,@ varchar(99)=''
SELECT @+=n
FROM
  (
    SELECT top 99 n 
    FROM
      (
         SELECT top 99substring(@i, row_number()over(order by 1/0), 1)n
         FROM sys.messages
      )c
    ORDER BY CHARINDEX(CHAR(ascii(n)/32+48),@s),n
  )d
SELECT @
```
**[Fiddle](https://data.stackexchange.com/stackoverflow/query/511595/post-determined-array-sorting)**
[Answer]
# [APLX](http://www.dyalog.com/aplx.htm), 19 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319)
```
s[(∊(⎕a⎕A⎕D)[a])⍋s]
```
`⎕a⎕A⎕D` lower upper digits
`(`…`)[a]` reorder according to array *a*
`∊` flatten
`(`…`)⍋s` according to that "alphabet", give the indices that would sort string *s*
`s[`…`]` use that to reorder *s*
[Answer]
# Python 2, 121 Bytes
```
lambda a,s:"".join(sum([[sorted(filter(eval(u),s))for u in["str.islower","str.isupper","str.isdigit"]][i]for i in a],[]))
```
[Answer]
# Clojure, 74 bytes
```
#(apply str(mapcat sort(for[i %](re-seq([#"[a-z]"#"[A-Z]"#"[0-9]"]i)%2))))
```
For each value in first list, gets appropriate regex and apply it to the input string. The result is a list of lists of symbols which match the regex. Then sort each one and concatenates the result into one list and transform it to string.
You can see it online here: <https://ideone.com/dqAkxg>
[Answer]
## [Retina](https://github.com/m-ender/retina), ~~43~~ 39 bytes
Byte count assumes ISO 8859-1 encoding. The trailing linefeed is significant.
```
2=`.
!$&"
T04`¶d`#^@%
O`\W?.
O`.\w+
\W
```
Input is expected to be the sort order as a zero-based list without delimiters on the first line, and the string to be sorted on the second line, e.g.
```
120
fOo42BaR
```
[Try it online!](http://retina.tryitonline.net/#code=Mj1gLgohJCYiClQwNGDCtmRgI15AJQpPYFxXPy4KT2AuXHcrClxXCg&input=MTIwCmZPbzQyQmFS)
### Explanation
I will use the above input example to walk you through the code:
```
120
fOo42BaR
```
**Stage 1: Substitution**
```
2=`.
!$&"
```
The regex itself is just `.` (matches any non-linefeed character), which is surrounded with `!..."`. However, the `2=` is a *limit* telling Retina to apply the substitution only to the second match of the regex. So we get this:
```
1!2"0
fOo42BaR
```
**Stage 2: Transliteration**
```
T04`¶d`#^@%
```
A transliteration stage simply does a character-by-character substitution. The `¶` represents a linefeed and `d` expands to `0123456789` (although we can ignore all digits after `2`). That means, this transliteration corresponds to the following mapping:
```
¶012
#^@%
```
The `04` at the front are two limits, which together indicate that only the first four characters from this set should be transliterated. That happens to be the digits on the first line, as well as the linefeed separating the two lines, so we get this:
```
@!%"^#fOo42BaR
```
At the front of the string we've now got three pairs of these characters:
```
@!
%"
^#
```
Note that the second characters of the pairs are simply in their normal ASCII order (and will always be the same). We'll use these later to sort the groups of characters in the main input into the required order.
The first characters are bit more interesting: their significance is that `%` comes before digits in the ASCII table, `@` comes before upper case letters (but after digits), and `^` comes before lower case letters (but after upper case letters). This will help us group the position markers (i.e. the second character in each pair) with the right set of characters.
**Stage 3: Sort**
```
O`\W?.
```
This is a simple sort stage. It matches two characters if the first one isn't a word character (thereby matching all three pairs I just talked about) or a single character otherwise (matching each character of the main input individually), and sorts those strings. This has two purposes: it brings the characters *within* each group in the correct order (and since sorting is stable, this order won't be messed up in the next stage), and it due to the `%@^` markers, it inserts the pairs in the right positions:
```
%"24@!BOR^#afo
```
**Stage 4: Sort**
```
O`.\w+
```
This stage sorts all matches of the `.\w+` regex which, due to greediness, matches one position marker (i.e. one of `!"#`) together with all the word characters after it. That is, it sorts these three strings, whose order is determined solely by the marker character:
"24
 !BOR
 #afo
While this shuffles around those markers (while leaving the other three markers in place), most importantly it brings the digits and letters in the correct order:
```
%!BOR@"24^#afo
```
**Stage 5: Substitution**
```
\W
```
All that's left is a little clean-up, where we remove all the markers by matching them and replacing them with nothing.
[Answer]
# Ruby, 56 bytes
Ported from @Dennis answer.
```
->a,s{s.chars.sort_by{|c|a.index(3-c.ord/32).to_s+c}*''}
```
An alternate 58 bytes solution that I like better, inspired by @Neil and modified slightly from his answer.
```
->a,s{a.map{|i|s.scan([/[a-z]/,/[A-Z]/,/\d/][i]).sort}*''}
```
[Try either version online!](https://repl.it/Cbi9) (commented-out version is the alternate solution)
[Answer]
# JavaScript (ES6), 65
Note: 'natural' ASCII order is 0-9, A-Z, a-z, that is just the opposite of the OP 0,1,2. So
* order the string adding invalid chars to separate runs
* split it in 3 segmenents - invalid chars mark each
* get segments one by one in the requested order
* reassemble
```
s=>w=>w.map(w=>[...'^@'+s].sort().join``.split(/\W/)[2-w]).join``
```
```
F=s=>w=>w.map(w=>[...'^@'+s].sort().join``.split(/\W/)[2-w]).join``
;[['201','a1B2c3','123acB']
,['210','aAaA909UuHWw9gh2','02999AAHUWaaghuw']
,['210','6Bx43','346Bx']
,['102','jfjf33g','ffgjj33']
,['021','AbC13','b13AC']
,['120','Qfl0l','Q0fll']
,['012','9870abcABC','abcABC0789']
,['021','test123','estt123']
,['201','WHAT','AHTW']
,['201','WhAt','htAW']
,['102','102BACbac','ABCabc012']]
.forEach(t=>{
  var w=t[0],s=t[1],k=t[2], r=F(s)([...w])
  console.log(w,s,r,(r==k?'OK':'KO (expected '+k+')'))
})
```
[Answer]
## Haskell, ~~62~~ 63 bytes
```
a#b=[c|i<-b,c<-[' '..],d<-a,d==c,div(fromEnum c)16==[6,4,3]!!i]
```
Usage example: `"cD12ab" # [2,0,1]` -> `"12abcD"`.
How it works:
```
i<-b                                  -- loop i through the input array
   [c|   c<-[' '..]]                  -- loop through all chars c
       d<-a                           -- loop through all chars d in the input string
       d==c                           -- and keep those that are in the input string
       div(fromEnum c)16==[6,4,3]!!i  -- and where the the ascii value divided by
                                      -- 16 equals the number from [6,4,3] indexed
                                      -- by the current i
```
Edit: @Christian Sievers found a bug. Thanks! Fixed for 1 additional byte.
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 15 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
┐°!'àÉgYg8∟╗`╖ë
```
[Run and debug it online](http://stax.tomtheisen.com/#c=%E2%94%90%C2%B0%21%27%C3%A0%C3%89gYg8%E2%88%9F%E2%95%97%60%E2%95%96%C3%AB&i=%5B%22a1B2c3%22%2C%5B2%2C0%2C1%5D%5D&a=1)
This 15 byte submission is [packed](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax) into a variant of the CP437 character set. The corresponding ascii representation takes 18 bytes:
```
EVlVd+26/s@:fs{[Io
```
Pretty sure it can be further trimmed down though.
```
E                   Put the two inputs on main stack
 Vl                 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
   Vd               "0123456789"
     +              Concatenate
      26/           Partition to blocks of size 26 (array `a`)
         s@         Index array `a` with the input index array
           :fs      Flatten to get a string `s`
              {[Io  Order the input string
                        Using the char array `s` as the key
                    Implicit output
```
`VlVd+` can also be `VLA|(`, which left rotates the `0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ` by ten elemenets. The whole code can also be `VlVd+26/,e@:f,{[Io`, which reads the input stack twice instead of reading them all at the beginning to the main stack, and uses a different (more traditional) input format, as shown in [this](http://stax.tomtheisen.com/#c=%E2%94%90%C2%B0%21%E2%86%90%E2%95%9B%E2%95%96%E2%98%BC01%E2%97%98%E2%95%AB%C2%BD%C2%A7%2A%E2%96%8C&i=%5B2%2C0%2C1%5D%0Aa1B2c3&a=1).
[Answer]
# [Dyalog APL](http://goo.gl/9KrKoM), 22 [bytes](http://meta.codegolf.stackexchange.com/a/9429/43319)
```
s[s⍋⍨∊(819⌶⎕A)⎕A⎕D[a]]
```
`(819⌶⎕A)` fold the uppercase alphabet to lowercase
`(`…`)⎕A⎕D[a]` lower upper digits reordered according to array *a*
`∊` flatten
`s⍋⍨` for string *s*, get the indices that would sort *s* according to that "alphabet"
`s[`…`]` use that to reorder *s*
[Answer]
## PowerShell v2+, 107 bytes
```
param($n,[char[]]$s)-join(-join(($s=$s|sort)|?{$_-ge97}),-join($s|?{$_-in65..96}),-join($s|?{$_-lt58}))[$n]
```
I'm exploring algorithms using regex, but thus far they all seem longer.
Takes input as explicit array `$n` (see examples below) and string `$s` which is immediately cast to a char-array. We're then constructing three elements of a new dynamic array, each of them encapsulated with a `-join`:  
- `(($s=$s|sort)|?{$_-ge97})`  
- `($s|?{$_-in65..96})`  
- `($s|?{$_-lt58})`
The first we take `$s` and run it through `Sort-Object`. Thankfully, since we've already cast it as a char-array, it's case-sensitive sorting. That gets re-saved into `$s` and then piped to a `Where-Object` with a clause of greater than `97` (i.e., ASCII lowercase `a-z`). The second is for `A-Z` and the third for `0-9`.
Thus we now have an array of strings, where each string is composed one of the three character types and is sorted. We slice that with `[$n]` and then `-join` the result together to form our final output string. That is left on the pipeline and printing is implicit.
## Test Cases
```
PS C:\Tools\Scripts\golfing> $test = (@(2,0,1),'a1B2c3'), (@(2,1,0),'aAaA909UuHWw9gh2'), (@(2,1,0),'6Bx43'), (@(1,0,2),'jfjf33g'), (@(0,2,1),'AbC13'), (@(1,2,0),'Qfl0l'), (@(0,1,2),'9870abcABC'), (@(0,2,1),'test123'), (@(2,0,1),'WHAT'), (@(2,0,1),'WhAt'), (@(1,0,2),'102BACbac')
PS C:\Tools\Scripts\golfing> $test |%{"($($_[0]-join',')) & $($_[1])".PadRight(28)+" -> " + (.\post-determined-array-sorting.ps1 $_[0] $_[1])}
(2,0,1) & a1B2c3             -> 123acB
(2,1,0) & aAaA909UuHWw9gh2   -> 02999AAHUWaaghuw
(2,1,0) & 6Bx43              -> 346Bx
(1,0,2) & jfjf33g            -> ffgjj33
(0,2,1) & AbC13              -> b13AC
(1,2,0) & Qfl0l              -> Q0fll
(0,1,2) & 9870abcABC         -> abcABC0789
(0,2,1) & test123            -> estt123
(2,0,1) & WHAT               -> AHTW
(2,0,1) & WhAt               -> htAW
(1,0,2) & 102BACbac          -> ABCabc012
```
[Answer]
# 32-bit x86 machine code, 70 bytes
In hex:
```
fc31c031c95189e3ac84c0740a34cf0404880c0341ebf189fe9160ac88c2c0e805d788c652ac88c2c0e805d788c658740e6639d076029241aa92aa4e4febdc85c96175d658c3
```
This procedure expects character class sorting order to be a 3-char (0..2) NULL-terminated string in `ESI` and the string to sort in `EDI`. Sorting is done in-place using extremely sub-optimal (performance-wise) version of bubble sort.
```
0:  fc                  cld
1:  31 c0               xor eax, eax
3:  31 c9               xor ecx, ecx
5:  51                  push ecx        ;Allocate 4 bytes on the stack
6:  89 e3               mov ebx, esp    ;char EBX[4]
_loop0:                                 ;Parsing class order string
8:  ac                  lodsb
9:  84 c0               test al,al      ;Break on NULL
b:  74 0a               jz _break0
d:  34 cf               xor al, 0xCF    ;AL=~atoi(AL)
f:  04 04               add al, 4       ;'0'->3, '1'->2, '2'->1
11: 88 0c 03            mov [ebx+eax], cl    ;EBX[AL]=CL
14: 41                  inc ecx
15: eb f1               jmp _loop0
_break0:
17: 89 fe               mov esi,edi
19: 91                  xchg eax,ecx    ;ECX=0
_bsort:
1a: 60                  pusha
_cx2b:
1b: ac                  lodsb           ;Get the first char to compare
1c: 88 c2               mov dl,al       ;Save to DL
1e: c0 e8 05            shr al,5        ;Char class: [0-9]->1, [A-Z]->2, [a-z]->3
21: d7                  xlat            ;AL=EBX[AL] - priority for the char class 
22: 88 c6               mov dh,al       ;... goes to DH
24: 52                  push edx        ;First "comparable char" in DX goes to the stack
25: ac                  lodsb           ;Get the second char to compare
26: 88 c2               mov dl,al       ;\
28: c0 e8 05            shr al,5        ; > Same as the above
2b: d7                  xlat            ;/
2c: 88 c6               mov dh, al      ;Second "comparable char" in DX
2e: 58                  pop eax         ;The first one goes to AX
2f: 74 0e               jz _endpass     ;ZF is set by the last 'shr', and only on AL==0
31: 66 39 d0            cmp ax,dx       ;Upper halves of 32-bit regs may contain trash
34: 76 02               jbe _sorted
36: 92                  xchg eax,edx    ;Now AX<=DX
37: 41                  inc ecx         ;Swap counter
_sorted:
38: aa                  stosb           ;Store AL in-place
39: 92                  xchg eax,edx    ;AL=DL
3a: aa                  stosb           ;Store the second char
3b: 4e                  dec esi         ;Move pointers...
3c: 4f                  dec edi         ;...back one byte
3d: eb dc               jmp _cx2b       ;Repeat with the next two chars
_endpass:
3f: 85 c9               test ecx,ecx    ;Full pass completed, checking # of swaps made
41: 61                  popa            ;Restores ECX(0), ESI, EDI. Doesn't affect flags
42: 75 d6               jnz _bsort      ;If there were changes, repeat
_end:
44: 58                  pop eax         ;Deallocate EBX[]
45: c3                  ret
```
[Answer]
## Emacs Lisp, 183 bytes
```
(lambda(s p)(let(l u n)(apply'concat(mapcar(lambda(l)(sort l'<))(dolist(e(string-to-list s)(mapcar(lambda(i)(nth i(list l u n)))p))(push e(cond((< ?` e)l)((< ?@ e)u)((< ?/ e)n))))))))
```
Slightly shorter than Java...
[Answer]
**Clojure, 77 bytes**
```
#(apply str(mapcat sort(map(group-by(fn[v](condp <(int v)90 0,57 1,2))%2)%)))
```
Not quite as short as the `re-seq` based one, and I couldn't figure out how to express that "`(apply str(mapcat sort(map(...))))`" in less space. `group-by` creates a hash-map which can be used as a function, when queried with an ingeger between 0 and 2 it returns the corresponding group, this orders the three different classes of characters.
This would be more compact than the `re-seq` solution if there were more character classes to handle as this only takes 5 extra characters / group like `57 1,` instead of 8 for expression like `#"[a-z]"`.
[Answer]
# Python 2, ~~140~~ ~~117~~ ~~101~~ ~~100~~ 99 bytes
Everyone say, "Ewww!". At least it's readable... *cough not really cough*
```
lambda l,s:`sorted(s,key=lambda c:[[c<'a',c<'A'or'Z'<c,c>'9'][l[i]]for i in 0,1,2]+[ord(c)])`[2::5]
```
[**Try it online**](https://repl.it/Cb9d/5)
[Answer]
# [R](https://www.r-project.org/), 101 bytes
```
function(a,s,o=unlist(list(letters,LETTERS,0:9)[a]))cat(o[sort(match(strsplit(s,'')[[1]],o))],sep='')
```
Creates a vector with a-z, A-Z and 0-9 in given order and reorders characters of input string to match this ordering. 
[Try it online!](https://tio.run/##hZFPa4MwGMbv/RTCDiYshSSWtdnWQZSCh126WTw4D1GMVpwWE@m@vbPaljH7J4f3EJ7f8zwvb91K43XayqaM9bYqgUAKVcumLLZKg2EkWie1Qu8rz1t9fCL8zGAgQghjoUEVqKrW4FvoOANK12pXbDVQyDRhEJAwRBWEIVLJbtn9tBLEgCIDI4PAR4IMUxCbxpYJXw5e5ldpwgfj75u@dYNQS8T25Ah3GD7CXHCG2aZx/T1LM/rfpocxZYxx7m58IdKs2Y9tnuyf2Y0Kg40162Q9S/r@dGBzmUvLSq/SPStlmueW1dMH9Lw9jxxyNzkiFndOyfTcei0LXNxj11gWxSmXnFuzxRyLKOa2c9mgZwcBni/YuLhOlO6ucnvtTnMQTUZH913u3Wg@0Nz1/AtoxvVdNNPcH5@KYGpzJxLxFX5ItZ1ub0xo@ws "R – Try It Online")
[Answer]
# J, 40 bytes
```
;@:{[:(<@/:~@}./.~2-64 96 I.3&u:)'aA0'&,
```
[Answer]
# Java 8, ~~221~~ ~~212~~ ~~193~~ 156 bytes
I should of course try to answer my own challenge as well. :) (And as usual in Java.)
```
a->i->{for(byte c[],j=0;j<3;System.out.print(new String(c)))java.util.Arrays.sort(c=i.replaceAll("[^a-z];[^A-Z];[^0-9]".split(";")[a[j++]],"").getBytes());}
```
-28 bytes saved thanks to *@cliffroot*.
**Explanation:**
[Try it here.](https://tio.run/##rZLNauMwFIX3eQrhlURjYTtDZ4yTgBwo3XQxtCUwxoVrVU7lUWRjyW3TkGfPKD/QjunKZCWB7vl0zuVU8Ap@3QhdPf/dcwXGoDuQejtCyFiwkqPKTdDOSkXLTnMra01vzpep1DbLx9@NLGpturVop/e2lXo1nyOOZnvw59Kfb8u6xcXGCsSdupoFSTWdJPcbY8Wa1p2ljZNYrMUbOqkxJ4R8fsLaFjaGmrq1mM8kbUWjgAumFPayJ/A/8iR7Yv6fwxH4ce5R0yhpsZd4JIOsurrK87HnEboSNnU2DCYk2e2TEXKpm65QLvU5/Gstn9HaLQSfnGQ5AnJYDkKcQtOozdHmcQ9bFI1RMEYh2hEKnIvGfQlhGvGJR5Kjpp9RaXx@@Z4WOuB/NAYsDuLH7nb5Fq9eoktxr9P3H8NMhsfI0VdYVVblZLIahDuwehtkxSIc7C3qBf1dqkANdRb2gsa/fgZQcJYuLpXVddGG0eC69Mu3vGUPF2O9MHuphoRBlLJFAfwE3I12@38)
```
a->i->{          // Method with integer-array and String parameters and no return-type
  for(byte c[],  //  Temp byte-array
      j=0;j<3;   //  Loop from 0 to 3 (exclusive)
      System.out.print(new String(c)))
                 //    After every iteration: print the byte-array as String
    java.util.Arrays.sort(
                 //   Sort the byte-array
      c=         //    After we've replaced the byte-array with
        i.replaceAll("[^a-z];[^A-Z];[^0-9]".split(";")[a[j++]],"").getBytes());}
                 //    all bytes of the uppercase letters, lowercase letters, or digits,
                 //    depending on the next number in the input-array
```
]