- Home /
Pick a memeber form the list only once
Hi Guys,
I have a List and what I am trying to do is select a random string from that list only once. When the list runs out of strings, refill it and do the procedure again. Any hints on how I can do this? I know the List has .Add and .Remove operations for example but I can't achieve what I want using only those.
Thanks
use List.RemoveAt(int index) where the index is a random number between including zero and the list length -1
Answer by Scribe · Aug 18, 2014 at 02:15 PM
randomly picking an object from a list only once is the exact same as a 'shuffle'
There are lots of easy algorithms on how to shuffle a list, a common one to use is the Fisher-Yates shuffle which can be implemented as:
for(int i = 0; i < list.Length; i++){
int j = Random.Range(i, list.Length);
String t = list[i];
list[i] = list[j];
list[j] = t;
}
Once shuffled you can then read from the list in order and will only ever get each entry once:
for(int k = 0; k < list.Length; k++){
Debug.Log(list[k]);
}
Scribe
This one is better than my approach. Takes away a hell lot of headache.
Thanks a lot Scribe, solved my problem!
Just a correction for other users that may have a similar case: In Lists, when you want to access the number of members you use "Count" while in Arrays it's "Length".
No problem, and thanks for the correction, I normally end up using arrays for everything :P
Answer by HarshadK · Aug 18, 2014 at 02:11 PM
The logic would be something like:
Have two set of lists - one to store all the possible values and one to select values from.
Add all items from your list of all possible values to your list to select values from.
Choose value from the list to select values.
Remove that chosen items from the list to select values.
Once your list to select values is empty add all items from your list of all possible values into your list to select values.
Repeat the procedure from #3 to #6 again and again.
Since you know the number of items you can add to your list to select values it would be efficient to have an array rather than list for that.
This seems one way to go, although Scribe's answer is more efficient. Thanks a lot for your input nonetheless! : )
Answer by kyzzer · Jun 03, 2021 at 11:53 AM
I know this is late, but for anyone else stuck you could use a separate Hashset along with your List and check if the gameobject is contained in the Hashset. If not then just -- your for loop. So for example something like this:
public List<Transform> list=new List<Transform>();
private HashSet<Vector3> track = new HashSet<Vector3>();
public GameObject orb;
private void Start()
{
for(var i = 0; i < 14; i++)
{
Vector3 spawnPts = list[Random.Range(0, list.Count)].position;
if (!track.Contains(spawnPts))
{
track.Add(spawnPts);
Instantiate(orb, spawnPts, orb.transform.rotation);
}
else {
i--;
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613160903im_/https://answers.unity.com/themes/thub/images/avi.jpg)