I am trying to randomly shuffle an array of strings in VBA, whilst ensuring that no item remains in the same place.
So far I've been adding all items to a collection, then to map the old array onto the shuffled array, I loop through items. Each item removes itself from the collection (so an item never transforms into itself). It then picks a random item from the remaining values, removes that from the collection, and adds itself back to the collection (so a latter item can pick it).
However this occasionally means the last item never gets picked, as the last item cannot pick itself, and all the other items can pick something amongst themselves
Indices is populated with all the people, targets and people are both 1 indexed arrays, where the latter is the array to be shuffled.
For i = 1 To UBound(people) ' loop through people
stillHere = HasKey(indices, "person" & i) 'only remove self from list if not already taken
If stillHere Then indecies.Remove "person" & i
randNum = Application.WorksheetFunction.RandBetween(1, indices.Count)
targets(i) = people(indices(randNum))
If indices.Count > 1 Then indices.Remove (randNum) 'don't remove the last item of the collection
If stillHere Then indices.Add i, "person" & i 'only add self back if not already taken
Next i
