C# reading .txt File FORMATTED

c#, file-io

Solution

EDIT 2 following your comment, that you wish to repeat the search 24 times a second.

First, let me caveat, if you are trying to play a stream of frames then looking up a list is the wrong approach. The right approach is beyond the scope of the question but, essentially you want to throttle the display of sequential data.

On the assumption that the values do not change, and your lookups are random, not sequential. You could try some code like this.

private readonly List<int> ids = new List<int>();
private readonly IList<double> values = new List<double>();

public void LoadData(string path)
{
    foreach (var line in File.ReadLines(path))
    {
        var pair = line.Split(' ');
        this.ids.Add(int.Parse(pair[0]));
        this.values.Add(double.Parse(pair[1]));
    }
}

public double Lookup(int id)
{
    return this.values[this.ids.FindIndex(i => i >= id)];
}

If more performance is required you could use the specialized binary search here.

EDIT after reading and hopefully, understanding

and assuming the frames are in ascending Id order.

double GetFrameValue(string path, int limit)
{
    string [] parts;
    foreach (var line in File.ReadLines(path))
    {
       parts = line.Split(' '); 
       var frameId = int.Parse[0];
       if (frameId >= limit)
       {
           break;
       }
    }

    return double.Parse(parts[1]);
}

This has the distinct advantage of only reading the file as far as necessary and not holding it all in memory. If you are going to read the file repeatedley at random frame positions then you'd be better off loading it all into some `Collection` with fast comparison performance, unless the file is very large.

How about,

IEnumerable<KeyValuePair<int, double>> ReadFrames(string path)
{
    foreach (var line in File.ReadLines(path))
    {
       var parts = line.Split(' '); 
       yield return new KeyValuePair<int, double>(
           int.Parse(parts[0]),
           double.Parse(parts[1]));
    }
}

var frames = new Dictionary<int, double>(ReadFrames("yourfile.txt"));

var frameIds = frames.Keys;
var values = frames.Values;

as stated in comments,

var frames = File.ReadLines("yourfile.txt")
    .Select(line => line.Split(' '))
    .ToDictionary(pair => int.Parse(pair[0]), pair => double.Parse(pair[1])); 

var frameIds = frames.Keys;
var values = frames.Values;

should work just as well.

Problem

I have a specific Textfile: ``` 197 17.16391215 198 17.33448519 199 17.52637986 200 17.71827453 201 17.9101692 202 18.10206387 203 18.29395854 204 18.48585321 205 18.67774788 206 18.86964255 207 19.06153722 ``` and so on. To be clear: First column (197,198,..) indicates a framenumber and the second column (17.xxx,...) indicates a position linked to the framenumber, and vice-versa. Now I want to separate each Line in different Arrays. With ``` string[] delimiters = new string[] {" ", "\r\n" }; string line = reader.ReadToEnd(); string[] test = line.Split(delimiters, StringSplitOptions.None); ``` I got one Array with all the entries from the Textfile. But I want all framenumbers (first column) in one Array and in another second Array all positions. My job I have to do is as follow: I will get a position number (e.g. 18.10) then I have to search in the .txt file in the second column for the nearest matching number and return the linked framenumber (in this case 202). My idea was to generate two matching arrays, search in one for the position and returning from the other for the framenumber. As I searched half a day on the internet I found many things like all the .select stuff, but not anything matching directly do my problem; but maybe I am to dumb at the moment. So thanks for any help. Hopefully you can understand my English :P

Original source

Related problems