Search Unity

string error

Discussion in 'Scripting' started by larswik, Nov 17, 2017.

  1. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312
    I have a player inventory that is an array of strings. I also have another array of strings that lists the items sold in the store. I am trying to return an 'int' by comparing the player Inventory array against the Store array. For example, if the first index of the player array has a value of "Sword", and sword is located in index 3 of the store array, I want to return 3.

    I did a web search and found the FindIndex and read about it, but I am not grasping it I guess. https://msdn.microsoft.com/en-us/library/03y7c6xy(v=vs.110).aspx

    Code (CSharp):
    1.        
    2. for(int i = 0 ; i < rInvArray.Length ; i++){
    3.             int num = Array.FindIndex(namesOfInventoryArray, playersData.rArray[i]);
    4.             print("Value is: " + num);
    5. }
    6.  
    I am getting this error and I am not sure what the differences are between a string and System.predicate string is?
    Thanks
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I wrote this up to be sure I got the syntax correct :)
    Pasted from Rextester:
    Code (csharp):
    1.  
    2.  string [] store = { "Bottle", "Gun", "Sword" };
    3.  string [] inv = { "Gun" , "Sword", "Bottle", "Nope!" };
    4.          
    5.  for(int i = 0; i < inv.Length; ++i) {
    6.     int c = Array.FindIndex(store, w => w.Equals(inv[i]));
    7.     Console.WriteLine("for " + inv[i] + "  c = " + c);
    8.     }
    9.  
    Edit: Sometimes I go to answer a post and miss other options lol
    You could change this line, for the same result:
    Code (csharp):
    1. int c = Array.IndexOf(store, inv[i]);
     
    Last edited: Nov 17, 2017
    sebastiansgames likes this.
  3. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312
    Thanks for the help. I started reading about Lambda today but I am having a tough time wrapping my head around it. So in the first response you had.

    Code (CSharp):
    1. int c = Array.FindIndex(store, w => w.Equals(inv[i]));
    .FindIndex() takes 2 arguments it seems. The first being the Array I want to search, in this case the store. The second argument is the array that I want to iterate through to find the match, if it exists. In this case it in the 'inv' Array. I also get the .Equals because you are comparing the left to the right for a match. But what I am not getting is the 'w => w'. Since it is w.Equals() I am guessing that the w represents the store array in some way?

    So every time the for loop increments it also increments the players inventory by one. The that gets checked against all of the indexes or the store, some how?

    Thanks again, trying to wrap my head around the Lambda.
     
  4. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312

    Wait, hang on. Your edited code is pretty much what I have already IndexOf(storeArray, playerArray); up above and that is what was giving me the error string System.string error?

    Just a hunch, I am reading from a saved file. I serialized to save but on loading the data I deserialze it. Could there be any System string formatting that is causing the problem since it is giving me an error comparing strings?
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    What you have above, where? Apologies if I'm missing something you wrote...Not sure about the formatting issue; first I'd check/confirm we had the same thing :)
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I believe the 'w' is each entry in the store array. Using that variable, it does the comparison.

    If you're interested, search for simple lambda examples to get the idea. :) (I did that a number of times lol).
     
  7. sebastiansgames

    sebastiansgames

    Joined:
    Mar 25, 2014
    Posts:
    114
    Kudos to methos for suggesting something as elegant as lambda expressions! But that might be a little complicated.

    A simpler solution to your original question is just to do a simple if then query in your for loop:

    Code (csharp):
    1.  
    2. int ReturnMatchingStoreIndex (string stringToMatch) {
    3. for (int i = 0; i < rInvArray.Length ; i++) {
    4. // if you get a return val of -1, that means the object wasn't found.
    5. int returnVal = -1;
    6. if (rInvArry[i] == stringToMatch) {
    7. returnVal = i;
    8. break;
    9. }
    10. return (returnVal);
    11. }
    12. }
    13.  
    Then just iterate through your player inventory array sending every string in the array to ReturnMatchingStoreIndex.

    I might add that arrays of strings is sorta cumbersome way to approach inventory. Maybe consider an enum of weapon types that you then put into a master array. Or better yet, write yourself a base weapons class that has a built in indexNumber. Then your array for both the player inventory and the store would be arrays of type weapon. You can then access the inventory number whenever you like giving you a lot more flexibility instead of having to parse strings continuously. Lots of ways to skin the cat, though. Good luck!
     
  8. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    It's always good to have options. :)

    I do agree that strings aren't the best, but each project is unique..
    and sometimes 1 problem at a time :) heh.
     
    sebastiansgames likes this.
  9. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312
    Thanks guys @methos5k & @sebastiansgames I got it working just fine tonight. This was just a small part of a larger thing I was trying to accomplish. I am working on Saving and Loading the game right now. My player inventory aren't strings, they are actually Buttons with images. User clicks the inventory button and the objects are created. I included an image of the purchased player inventory as an example.

    The problem I had was in saving. In Objective C I could save reference objects in an NSData class and save that to the hard drive and restore NSData to NSButton again. I ran in to trouble trying to save reference types , I think you call it, so I basically got the array of button objects and then got their transform.name. From that point I just added the name strings to an array which was savable to the hard drive. Then I just reversed that process to repopulate the player inventory. I got it working tonight with your guys help.

    Thanks for the assist! Screen Shot 2017-11-17 at 1.10.59 AM.png
     
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Cool, I'm glad you got it working :)
     
  11. Fido789

    Fido789

    Joined:
    Feb 26, 2013
    Posts:
    343
    No offense, but how can you call such a mess that won't even compile "a simpler solution" and this
    Code (CSharp):
    1.         int ReturnMatchingStoreIndex(string stringToMatch)
    2.         {
    3.             return Array.FindIndex(rInvArray, i => i == stringToMatch);
    4.         }
    you call "a little complicated".

    Even if I would write your code correctly

    Code (CSharp):
    1.         int ReturnMatchingStoreIndex(string stringToMatch)
    2.         {
    3.             for (var i = 0; i < rInvArray.Length; i++)
    4.                 if (rInvArray[i] == stringToMatch)
    5.                     return i;
    6.             return -1;
    7.         }
    even then is the lambda solution far more readable than for loop.
     
    Last edited: Nov 17, 2017