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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Newby) filter rows from csv using linq

Discussion in 'Scripting' started by Louis_Amerongen, Feb 9, 2018.

  1. Louis_Amerongen

    Louis_Amerongen

    Joined:
    Jul 21, 2017
    Posts:
    19
    Hi,

    My final goal is to use data from a csv-file to instantiate filtered objects in Unity (with c#). The first step is to couple a csv in Unity.

    Linq is a very interesting way to achieve this. Next to csv, it can also be used to harvest other data sources.

    I found an interesting example on the website of Microsoft:
    https://docs.microsoft.com/en-us/do...compute-column-values-in-a-csv-text-file-linq

    My csv file looks like this:



    To use it in Unity I converted the example:

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6. using System.Linq;
    7. using System;
    8.  
    9. public class Linqtest : MonoBehaviour
    10.    
    11. {
    12.     public string output = "";
    13.     public float A = 35f, B = 150f, C = 750f, D = 400f;
    14.  
    15.     public Text teksten;
    16.  
    17.     public string[] line;
    18.  
    19.     void Start()
    20.    
    21.     {
    22.    
    23.         string[] lines = System.IO.File.ReadAllLines("./Assets/LINQ/Scores.csv");
    24.  
    25.         MultiColumns(lines);
    26.  
    27.     }
    28.     public void MultiColumns(IEnumerable<string> strs)
    29.     {
    30.        
    31.         IEnumerable<IEnumerable<int>> multiColQuery =
    32.  
    33.            
    34.             from line in strs
    35.             let elements = line.Split(',')
    36.             let scores = elements.Skip(1)
    37.             select (from str in scores
    38.                     select Convert.ToInt32(str));
    39.  
    40.     var results = multiColQuery.ToList();
    41.  
    42.             // Loop en berekenen Queries:
    43.  
    44.         int columnCount = results[0].Count();
    45.        
    46.         output = "";
    47.  
    48.         for (int column = 0; column < columnCount; column++)
    49.         {
    50.             var results2 = from row in results
    51.                            select row.ElementAt(column);
    52.    
    53.             double average = results2.Average();
    54.             int max        = results2.Max();
    55.             int min        = results2.Min();
    56.             int sum        = results2.Sum();
    57.  
    58.             output = output + (string.Format("Examennummer #{0} Gemiddelde: {1:##.##} Beste Score: {2} Laagste Score: {3} Opgeteld: {4}",
    59.                           column + 1, average, max, min, sum));
    60.             output = output + "\n";
    61.         }
    62.     }
    63.     void OnGUI()
    64.     {
    65.         GUI.Label(new Rect(A, B, C, D), output);
    66.     }
    67. }
    68.  
    Like you can see, the results are columns. I've spend some evenings to convert the code that it shows rows. Unfortunately without a good result.

    Can someone advise me how I can show the rows filtered by the first column?
    For example, show the data from rows called A.


    Thanks in advance,

    Louis
     
  2. Fido789

    Fido789

    Joined:
    Feb 26, 2013
    Posts:
    343
    You can do it like this:
    Code (CSharp):
    1. var fiteredResults = System.IO.File.ReadAllLines("./Assets/LINQ/Scores.csv")
    2.     .Select(l=>l.Split(',').Select(s=>s.Trim()).ToArray())
    3.     .Where(a=>a[0] == "A");
    4.  
    5. foreach (var filteredResult in fiteredResults)
    6. {
    7.     Debug.Log(String.Join(",", filteredResult));
    8. }
    or if you prefer:
    Code (CSharp):
    1. var fiteredResults =
    2.  from a in (from l in System.IO.File.ReadAllLines("./Assets/LINQ/Scores.csv") select (from s in l.Split(',') select s.Trim()).ToArray()) where  a[0] == "A" select a;
    3.  
    4. foreach (var filteredResult in fiteredResults)
    5. {
    6.     Debug.Log(String.Join(",", filteredResult));
    7. }
     
    Last edited: Feb 9, 2018
  3. Louis_Amerongen

    Louis_Amerongen

    Joined:
    Jul 21, 2017
    Posts:
    19
    Thank you very much for the answer Fido!

    I hope to test it today.

    Regards Louis
     
  4. Csyoung29

    Csyoung29

    Joined:
    Jun 19, 2018
    Posts:
    1
    tested?
     
  5. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,294
    Also slow, and not very garbage allocation friendly.

    Although this is a necropost (kinda), people should know that this is far from optimal.