1

I've been trying to pull values from an enum and store them as a String in an array. However, depending on a variable, the values have to be unique, i.e. the same value can't be used twice.

I've used the following code to pull values:

public enum Colour
{
    ROOD, GEEL, GROEN, BLAUW, PAARS;

    public Colour getRandomColour(Random rn)
    {
        return values()[rn.nextInt(values().length)];
    }
}

However, this can give duplicate values.

It seems that the values of my enum refuse to be put in code blocks. Sorry!

EDIT:

for (int i = 0; i < code.length; i++) 
            code[i] = kleur.getRandomColour(rn).toString();

It fills up the array 'code'. The array-length depends on several factors but it will always be smaller than or equal to the amount of values in the enum.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 2
    Did you try with a set instead of an array? – BackSlash Mar 21 '18 at 11:07
  • it would be interesting to see the part where you call `getRandomColour` and push the value in your array – jhamon Mar 21 '18 at 11:08
  • Do you want to get random [permutation](https://en.wikipedia.org/wiki/Permutation) of all your enum values? Because if you call `getRandomColour` more than there is values in your enum you must get duplicate value at least once. – MatheM Mar 21 '18 at 11:10
  • Show your code where you "pull values from an enum". – lexicore Mar 21 '18 at 11:11
  • [Java generating non-repeating random numbers](https://stackoverflow.com/q/16000196) – Bernhard Barker Mar 21 '18 at 11:16
  • 1
    Possible duplicate of [Generating a random enum value continuously without getting the same value twice](https://stackoverflow.com/questions/18145766/generating-a-random-enum-value-continuously-without-getting-the-same-value-twice) – Bernhard Barker Mar 21 '18 at 11:17
  • The difference is that due to the nature of my project, I have to use an array since it has to be 2-dimensional. The post Dukeling linked used an ArrayList. – Nick Lersberghe Mar 21 '18 at 11:26

3 Answers3

1

You could populate a list with all values from your Colour enum, shuffle, and then just access values sequentially:

List<Colour> colourList = Arrays.asList(Colour.values());
Collections.shuffle(colourList);

Then, just iterate the list and access the colors in order, which of course should be random since the collection was shuffled:

for (Colour c : colourList) {
    // do something with c
}

You could also go with your current approach, and store the colors into a set, rather than an ArrayList. But the problem there is that you may draw a duplicate value any number of times, and the chances of that happening as the set increases in size will go up.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • You have to use `List colours = Arrays.asList(Colour.values()); Collections.shuffle(colours);` instead of `Collections.shuffle(Arrays.asList(Colour.values()));` since Collections.shuffle doesn't return any value. – statut Mar 21 '18 at 11:18
  • Is there a way to apply this to an Array rather than a list? The 2-dimensions are quite important in my project (or since I'm a java novice, i don't know a better way to do it yet). – Nick Lersberghe Mar 21 '18 at 11:27
  • I don't recall seeing two dimensions in your question, but you can just run what I suggested N times to generate N dimensions of random sets of enum values. You could go with what you have, but using a set, but then you have to deal with needing to draw multiple times to get the next unique value. – Tim Biegeleisen Mar 21 '18 at 11:29
  • I just realised, this specific array is 1-D rather than 2-D. My project is a game of Mastermind and I'm using a 2-D array for the board while this was about the solution. I just need the values. ArrayList it is then. Thanks! – Nick Lersberghe Mar 21 '18 at 11:41
0

Use a temporary list to check if the new value already exist and continue to generate a new value until a unique is found.

for (int i = 0; i < code.length; i++) {
   String next = kleur.getRandomColour(rn).toString();
   List<String> tempList = Arrays.arrayAsList(code);
   while (tempList.contains(next);
     next = kleur.getRandomColour(rn).toString();
   }
   code[i] = next;
}
Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • I found a slightly better solution to my problem. Store the values as String in an array and use the indexes to reference that String. – Nick Lersberghe Mar 21 '18 at 14:51
0

For those still wondering, I might have found a good solution. Store the values of the array in an ArrayList. Using a for-loop to pull a value from the ArrayList then remove that index, essentially eliminating duplicates.