- Home /
Select random object in List using Linq
Hey all,
I'm in the process of creating an objectRecycler with the base code provided by prime31 in one of his youtube tutorials. Linq is completely new to me, but I have some SQL knowledge so it's not completely new territory I guess.
What I need to do is select a random GO in my List that also is also set to active == false. I've looked through the syntax from googling my question, but I can't quite wrap my head around it. Here's my query:
GameObject freeObject = ( from item in objectList
where item.active == false
select item ).FirstOrDefault;
Is there any short and simple way to select a random object that is qualified under my query as well? I'd really like to stick with Linq as it has some great functionality and I'd like to start incorporating it in lots of places, so please refrain from posting alternative methods ( ie standard array shuffling ). I also know that utilizing the extension method FirstOrDefault may not be appropriate for my selection, and I'm reading through the MSDN documentation but as I'm sure most of you know, Microsoft's documentation is definitely not novice friendly. Thanks in advance.
Answer by dannyskim · Dec 08, 2011 at 09:12 PM
I semi-figured it out:
var randomSelection = objectList.Where( i => i.active == false );
var freeObject = randomSelection.ElementAtOrDefault( new System.Random().Next() % randomSelection.Count() );
The reason I say 'semi' is because now I have to set my objectRecycler class to inherit from MonoBehaviour, and on top of that I have to add 'using System;' as an assembly reference, which might be adding unneeded overhead to my project size. Not only that, but when I reference 'Random.Range', I now have to reference which assembly it is coming from such as 'UnityEngine.Random.Range' and 'System.Object.Instantiate' and such.
If anybody has a better solution, I'm all ears. This solution will do for now, but if there is something else that I can do that doesn't add assembly overhead I would very much appreciate the suggestions.
I think you might be worrying a little too much about the overhead. If you've referenced system in any other file (or any asset bundle you use does) it's already in there. I'd assume the entire Unity engine assembly(ies?) are there too already as part of the deploy (they must use random internally).
You can combine your existing into one line. Another option is to do:
var randomSelection = objectList.Where( i => i.active == false ).OrderBy(n=>UnityEngine.Random.value).FirstOrDefault(); //use whatever you prefer for random
One question: is the lifetime of your objects (i.e. how long they are active) inherently random? If so you could add a field and use that (then take the most recently dead one). Depending on the lifetimes that may produce a cycle that is random enough for you.
var randomSelection = objectList.Where( i => i.active == false ).OrderBy(n=>n.TimeOfDeactivation).FirstOrDefault();
Your answer
Follow this Question
Related Questions
Unity doesn't recognize "List" object type (Linq) 2 Answers
GameManager value tracking design issue 1 Answer
DbLinq and SQLite 1 Answer