Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Getting all objects in an array containing a matching variable

Discussion in 'Scripting' started by Barachiel, Sep 28, 2014.

  1. Barachiel

    Barachiel

    Joined:
    Nov 25, 2012
    Posts:
    147
    Hi all, just a quick question.

    I have an array containing multiple instances of the same script (they're all attached to different game objects), and one of the variables these scripts have is a string, called module.
    EDIT: Forgot to mention, the module variable is actually a string array, usually (but not always) containing 2 items.

    What I'm looking to do is find all of the scripts in my array where the module variable matches a given string, then add all of the matches to a new array.

    For example, finding everything in the array where module is equal to "Test", then making a new array containing the results.

    Apologies if I sound unclear or vague, haven't been getting enough sleep. =P
    Any help on this matter is much appreciated.

    EDIT2: I forgot to mention that I'm pretty sure I can do this in C#, but am currently using Unityscript.
     
    Last edited: Sep 28, 2014
  2. djfunkey

    djfunkey

    Joined:
    Jul 16, 2012
    Posts:
    201
  3. Barachiel

    Barachiel

    Joined:
    Nov 25, 2012
    Posts:
    147
    That's a pretty handy reference, thank you. I knew about .Contains and I actually have some idea of how to do it in C#.
    I had, however, neglected to mention that I'm currently writing in Unityscript. That's a pretty severe oversight, my apologies.

    EDIT:
    This is the relevant part of what I have:

    Code (JavaScript):
    1. import System.Collections.Generic;
    2. import System.Linq;
    3.  
    4. var modules        :    Module[];
    5. var beginModule    :    Module;
    6.  
    7. function RandomWithTag(modules:Module[] ,matchingTag:String)
    8. {
    9.     var matchingModules    =    modules.Where(modules => modules.tags.Contains(matchingTag)).ToArray;
    10. }
    I clearly don't know how to write this in Unityscript though, getting 'Unexpected token' error from the modules written just after .Where .
     
    Last edited: Sep 28, 2014
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Doesn't really matter; most things (Contains, etc.) apply to Unityscript as well.

    --Eric
     
    djfunkey likes this.
  5. Barachiel

    Barachiel

    Joined:
    Nov 25, 2012
    Posts:
    147
    Woops, edited my post and checked the thread for new responses before submitting, but my timing must have been off. My last post was edited with relevant information.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Code (csharp):
    1. var matchingModules = modules.Where(function(modules) {return modules.tags.Contains(matchingTag);}).ToArray();
    (Not tested)

    --Eric
     
  7. Barachiel

    Barachiel

    Joined:
    Nov 25, 2012
    Posts:
    147
    The code returns an error, but certainly looks like something I can start fiddling with. The error is:
    I'm also getting:
    I haven't had this crop up earlier when referencing 'tags'. This is the variable in the Module script, with the strings assigned in the inspector:
    Code (JavaScript):
    1. public var tags   :   String[];

    EDIT: Well the main problem is solved and was stupidly easy and I'm clearly too tired if I didn't try it earlier (which I thought I had). I changed the variable names for the string arrays to be more clear, as well, since two scripts were using the same variable name and it was confusing me:
    Code (JavaScript):
    1. var matchingModules   =   modules.Where(modules.moduleTags.Contains(tagToMatch)).ToArray;
    It still doesn't recognize moduleTags as a member of Modules[] however.
     
    Last edited: Sep 28, 2014
  8. Barachiel

    Barachiel

    Joined:
    Nov 25, 2012
    Posts:
    147
    Posting this as a new reply because after previewing it as an edit to the prior post it looks really cluttered and hard to find the relevant information.

    Okay, so after some experimentation it's because it wants me to specify which object in the array it's looking for.
    For example, this works:
    Code (JavaScript):
    1. print(modules[0].moduleTags[0]);
    But if I fail to specify which part of the array in either of those, it doesn't work.


    So with this:
    Code (JavaScript):
    1.  
    2. function GetRandomWithTag(modules:Module[],tagToMatch:String)
    3. {
    4.    var matchingModules   =   modules.Where(modules.moduleTags.Contains(tagToMatch)).ToArray;
    5. }
    6.  
    I get an error telling me that moduleTags isn't a member of modules, because I haven't specified which module in the array to get that info from.

    So, the question now is, how do I get it to check for the 'tagToMatch' in every string in the 'moduleTags' array?
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    That wouldn't work anyway, since Where needs a function, not a boolean. See the code I posted above.

    Indeed it's not. Honestly I'd just loop through the array; I've never been a huge fan of trying to construct convoluted queries with Linq, especially since doing things the "long way" is faster and performs fewer allocations than Linq anyway (and is IMO easier to understand):

    Code (csharp):
    1.     var matchingModules = new List.<Module>();
    2.     for (var i = 0; i < modules.Length; i++) {
    3.         if (modules[i].moduleTags.Contains (tagToMatch)) {
    4.             matchingModules.Add (modules[i]);
    5.         }
    6.     }
    --Eric
     
    Barachiel and djfunkey like this.
  10. Barachiel

    Barachiel

    Joined:
    Nov 25, 2012
    Posts:
    147
    I was actually thinking of just using a foreach loop, not sure why I was being so stubborn and trying to make it work with Linq.
    Thanks for the help, I appreciate it a great deal! =)