Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Help making method generic - retrieving data from xml spreadsheet

Discussion in 'Scripting' started by gareth_untether, Jan 20, 2020.

  1. gareth_untether

    gareth_untether

    Joined:
    Jan 5, 2018
    Posts:
    69
    I'm using QuickSheet to make ScriptableObjects from xml files and access the data in Unity

    I need a generic method for extracting the data because I have multiple spreadsheets.

    Each spreadsheet has three columns: ID, EN, ES.

    The script takes the ID and language code, then grabs the relevant data.

    The problem I have is that I don't know how to get an enum in a generic way (not even sure that's what I need to do?!).

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5. using UnityEngine;
    6.  
    7. [SerializeField] SerializedObjectSpreadshee serializedObjectSpreadshed;
    8.  
    9. public string GetData(int id, string languageCode)
    10. {
    11.     List<SerializedObjectSpreadshedData> items = new List<SerializedObjectSpreadshedData>();        // 1 Make a list
    12.  
    13.     items.AddRange(serializedObjectSpreadshed.dataArray);     // 2 Add the SO data
    14.  
    15.     AppleActionsData foundID = items.Find(x => x.ID[0] == id);        // 4 Search for the ID and add it to a list
    16.  
    17.     var foundAction = foundID.GetType().GetProperty(languageCode).GetValue(foundID, null);     // 5 Get the language data from the element
    18.  
    19.     var strings = ((IEnumerable)foundAction).Cast<object>()                           // 6 Convert language data to a string array
    20.                               .Select(x => x == null ? x : x.ToString())
    21.                               .ToArray();
    22.  
    23.     return strings[0].ToString();
    24. }
     
    Last edited: Jan 20, 2020
  2. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    I'm going to first start with, you do a lot of unnecessary and expensive work in here. There's no need to create a list, not a reason to ToArray the enumerable you got as 'foundAction', also foundAction is inherently an enumerable of object's so no need to cast.

    Also, how do you know that it's going to be an IEnumerable? How do you even know that the passed in 'languageCode' is a valid property?

    Anyways... this could be shortened up to:
    Code (csharp):
    1. public string GetData(int id, string languageCode)
    2. {
    3.     var foundId = serializedObjectSpreadshed.dataArray.FirstOrDefault(o => o.ID[0] == id); //you already have linq, use it
    4.     if(foundID == null) return null; //id may not have been found
    5.  
    6.     var foundActions = foundID.GetType().GetProperty(languageCode).GetValue(foundID, null) as IEnumerable; //this should be refactored, there is probably a better way
    7.     if(foundActions == null) return null; //languageCode may have been invalid
    8.  
    9.     return System.Convert.ToString(foundActions.FirstOrDefault()); //Convert.ToString handles nulls for you
    10. }
    To refactor this even cleaner, I'd have to see the implementation of SerializedObjectSpreadshedData.

    ...

    As for enums. I'm not completely following how you expect this to work?

    Do you want a 'T GetData<T>' where the function returns the result not as a string, but instead converted to the T? How are you certain it is convertible? What are the types of 'languageCode' properties? Again, I'd like to see the imp for SerializedObjectSpreadshedData.