How can I randomize the Strings in the StringList similarly how this online tool works. If anyone is familiar with it, check this: http://textmechanic.co/Randomize-List.html
Asked
Active
Viewed 4,700 times
14
-
http://en.m.wikipedia.org/wiki/Fisher–Yates_shuffle – David Heffernan Dec 22 '12 at 20:16
-
1@DavidHeffernan Seriously what does this have to do with the question?! – Santos Oliveira Dec 22 '12 at 20:17
-
2@DavidHeffernan The fixed link is : http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle – TridenT Dec 22 '12 at 20:24
-
@DavidHeffernan Ah i thought you are sending me to a Fishermans link :) – Santos Oliveira Dec 22 '12 at 20:29
-
@DavidHeffernan You are welcome to post your solution. Nobody is holding you down :) – Santos Oliveira Dec 22 '12 at 21:06
-
@DavidHeffernan is there any point in arguing? let it be... – Dec 22 '12 at 21:18
-
Page about fishermen? I don't get that. – David Heffernan Dec 22 '12 at 21:20
-
Your link in your first comment above. It links to wikipedia/Fisher. Don't be silly, you know it because you've posted the corrected link *after* Santos's response. – GolezTrol Dec 22 '12 at 21:23
-
@Golez I didn't post a corrected link. I had not realized my link was eaten. I understand what you are all talking about now. – David Heffernan Dec 22 '12 at 21:26
3 Answers
25
One common algorithm to perform a shuffle is the Fisher-Yates shuffle. This generates uniformly distributed permutations.
To implement on a Delphi TStrings
object you can use this:
procedure Shuffle(Strings: TStrings);
var
i: Integer;
begin
for i := Strings.Count-1 downto 1 do
Strings.Exchange(i, Random(i+1));
end;
Now, whilst in theory this will generate uniformly distributed permutations, the actual performance depends heavily on the quality of the random number generator. This is discussed in Knuth's Art of Computer Programming, volume 2, section 3.4.2, Algorithm P.
Further reading:
- Fisher-Yates shuffle (Wikipedia)
- Jeff Attwood's two blog articles on shuffling: Shuffling and The Danger of Naïveté
- The intuition behind Fisher-Yates shuffling (Eli Bendersky)
- Art of Computer Programming, Donald Knuth, volume 2, section 3.4.2
- Shuffling (Wikipedia)

David Heffernan
- 601,492
- 42
- 1,072
- 1,490
-
-
1Yes, Santos, but why bother? Random(i+1) is equivalent to RandomRange(0, i). – Rob Kennedy Dec 23 '12 at 06:41
-
5It was @Rob who responded? And I don't understand why you adopt a sarcastic tone towards people that try do things as well as possible, and help you out along the way. – David Heffernan Dec 23 '12 at 08:53
-
1@DavidHeffernan yea however the solution that you provided is almost exact as GolezTrol :) – Santos Oliveira Dec 23 '12 at 09:20
-
2Not at all. Golez's code is skewed. Some permutations are chosen with higher prob than others. I suspect you don't want that. – David Heffernan Dec 23 '12 at 09:32
-
@delphirules What is your alternative algorithm that is algorithmically more efficient. Can you do it in fewer than N swaps? Pretty hard to see how that would be possible. – David Heffernan Aug 20 '14 at 14:25
-
@david-heffernan i don't know but this site randomize a large list in seconds, i wish to know what is the algotithm used : http://www.randomizelist.com/ – delphirules Aug 27 '14 at 17:31
-
@delphi Define large please. Which algo could do it in fewer than N swaps? And please give some timings for Fisher-Yates. – David Heffernan Aug 27 '14 at 17:33
-
@david-heffernan i tested with a list with about 10.000 itens ; it took minutes to finish. – delphirules Aug 28 '14 at 13:16
5
Just loop through the stringlist and give each item an different random place:
for i := StringList.Count - 1 downto 1 do
StringList.Exchange(i, Random(i+1));
[edit] Altered the loop a bit to make the shuffling uniform.

GolezTrol
- 114,394
- 18
- 182
- 210
-
-
2This answer demonstrates one of the Fisher-Yates errors discussed in Wikipedia, in the ["implementation errors"](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Implementation_errors) section. Although it still yields a shuffled result, which is all the question asked for, it's not a uniform shuffle algorithm. Quality of the RNG is orthogonal to that issue. – Rob Kennedy Dec 23 '12 at 06:39
-
@RobKennedy Okay. Good to know, and the explanation you point to makes it very clear. I've altered the loop a little. Used downto, because it makes the loop simpler. The `+1` is there to prevent an accidental implementation of Sattolo's algorithm. – GolezTrol Dec 23 '12 at 10:43
-
So I deleted all my comments since they are no longer applicable to your answer – David Heffernan Dec 23 '12 at 16:26
-
I found a couple more nice posts on this topic: http://www.codinghorror.com/blog/2007/12/shuffling.html http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html – David Heffernan Dec 23 '12 at 22:29
-
Thanks, but especially the first link is more applicable to the answer by Trident. – GolezTrol Dec 23 '12 at 23:53
-4
To randomize a TStrings
, create a comparer from TComparer
with random result value, and sort the TStrings
with it.
/// The Comparer
TMyShuffleComparer= class(TComparer<string>)
public
function Compare(const Left, Right: string): Integer; override;
end;
/// The randomizer
function TMyShuffleComparer.Compare(const Left, Right: TCard): Integer;
begin
// To sort, get a random number for compare result
Result := Random(100) - 50;
end;
/// How to call the comparer
procedure TMyStrings.Shuffle;
begin
Sort(TMyShuffleComparer.Create);
end;
or to call directly:
/// Shuffle
MyString.Sort(TMyShuffleComparer.Create);

TridenT
- 4,879
- 1
- 32
- 56
-
4-1 A sort compare function needs to define a total order. This doesn't. It's a simply terrible idea. I suggest that you delete the answer. Have a read of this, for example: http://blogs.msdn.com/b/oldnewthing/archive/2003/10/23/55408.aspx – David Heffernan Dec 22 '12 at 21:07
-
3Comparison functions that are inconsistent can lead to non-terminating sort functions and buffer overruns. They are not the way to shuffle a list. – Rob Kennedy Dec 23 '12 at 06:28
-
Whilst it is possible to use sorting algos to shuffle, this is not how to do it. Even when you get it right you have much more complex code that is slower than, for example, Fisher-Yates. – David Heffernan Dec 23 '12 at 09:17
-
I tested it according to your remarks and I now understand my mistake on the comparer. Trying to reply to the answer, I've fix my own error ;) – TridenT Dec 23 '12 at 14:44
-
This is a kind of novelty idea, **but**, as @Rob said, your comparing function has to be [**deterministic**](http://technet.microsoft.com/en-us/library/ms178091.aspx) (disregard SQL flavour), otherwise you end up with poorly shuffled resulting list. – Free Consulting Dec 27 '13 at 12:20
-
Also, your selection of random value prefers negative values: [-50, 49] – Free Consulting Dec 27 '13 at 12:24